⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_main.c

📁 给予mx21处理器的嵌入式系统的mmc卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 		sector: first sector number; * 		nr_sector: number of the sectos  * * Value Returned:  * 		0:	success. * 		1:	failure. * * Description:  * 	this routine will write data into indicated sectors.	 * * Modification History: * 	30 DEC,2001, Initial version.  			Yiwei Zhao  *****************************************************************************/static int mmcsd_write(	MMCSD_Dev *device, char * buffer,			u32 sector, u32 nr_sector){	int ret;	u32	i;	TRACE(" write to 0x%lx, number:0x%lx", (unsigned long)sector, (unsigned long)nr_sector);	for(i = 0; i < nr_sector; i++)	{		if(sector == (device->cur_sec+1))		{			/*			device->buff_pool[device->cur_num]=kmalloc(sizeof(UINT8)*device->blksize,							   GFP_KERNEL);			if(device->buff_pool[device->cur_num] == NULL)			{				FAILED("No Kernel Space");				return MMCSD_ERROR;			}			*///			TRACE("add into buffer pool");#ifdef MMCSD_DMA_ENDIAN_ERR			_mmcsd_cp_16_little_2_big(buffer,	 	//src						  device->tmp_pool[device->cur_num],	// target						  device->blksize);#else			memcpy(device->buff_pool[device->cur_num],			       buffer,			       device->blksize);#endif			if(device->cur_num == 0)			{				device->addr = sector*(device->blksize);			}			device->cur_num++;			device->cur_sec++;			sector++;			if(device->cur_num == MMCSD_MAX_MULTI_BLK)			{					// If the pool is full			//	TRACE("The Pool is Full...");#ifdef MMCSD_WRITE_DMA				ret = mmcsd_dma_write_blks(device);#else				ret = mmcsd_write_blks(device);#endif				if(ret != MMCSD_OK)				{					FAILED("mmcsd_write_blk failed");					return ret;				}				// cur_num should be zero			}		}		else 		{			if(i!=0) 			{				FAILED("Error!");				return MMCSD_ERROR;			}			//TRACE("Another Blk");#ifdef MMCSD_WRITE_DMA			ret = mmcsd_dma_write_blks(device);	// if the blk is not continous.#else			ret = mmcsd_write_blks(device);	// if the blk is not continous.#endif			if(ret != MMCSD_OK)			{				FAILED("mmcsd_write_blk failed");				return ret;			}			i--;	// i == 0			device->cur_sec = sector-1;		}	}	if( i == nr_sector)	{		return MMCSD_OK;	}		return MMCSD_ERROR;}MMCSD_STATUS mmcsd_write_blks(MMCSD_Dev *device){	int i,t,j,counter;	u32 state,ret,ret2,int_mask, temp32;	u16 temp16,*p16;	u32 addr;	u32	burst_len=8;	if(device->cur_num == 0)	{		mmcsd_free_buffer(device);		return MMCSD_OK;	}	ret=ret2=MMCSD_OK;	TRACE("enter mmcsd_write_blks.....");	g_selected_lock[device->port].device = device;	/**************************************************************	 * Check the Card Status	 **************************************************************/	state =MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		mmcsd_free_buffer(device);		return ret;	}	/**************************************************************	 * Mask Interrupt	 **************************************************************/	TRACE("Disable Interrupt..");	_MMCSD_Mask_interrupt(0x7F,&int_mask,device->port);	/**	 * End of Testing	 */	/**************************************************************	 * Set Block Length 	 **************************************************************/	i = 5;	while(i--)	{		ret = _MMCSD_SetBlockLen(MMCSD_MINIMUM_BLK_SIZE,device->cur_num,device->port);		if(ret)		{			TRACE("3)Set Block Len, ret = 0x%lx,state=%lx",(unsigned long)ret,(unsigned long)state);			TRACE("4)Try again...%d",i);			state = MMCSD_TRANSFER;			mmcsd_check_status(device,&state);		}		else	//ret == SUCCESS!		{			break;		}	}	if(ret)	{		mmcsd_free_buffer(device);		FAILED("5)Set Blocked Len Failed!");		return ret;	}	/********************************************************************	 * Begin to write 	 *******************************************************************/		addr = device->addr;	TRACE("6)address is 0x%lx (sector 0x%lx),blk number is %ld",			(unsigned long)addr,(unsigned long)(addr/512),(unsigned long)(device->cur_num));	_MMCSD_StopClk(device->port); 			if(device->cur_num == 1)	{		if(device->bit_width == 0)		{			_MMCSD_SetCmd(MMCSD_CMD24,addr,MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);			burst_len = 8;		}		else		{			_MMCSD_SetCmd(MMCSD_CMD24,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);			burst_len = 32;		}		g_mmcsd_cmd[device->port] = MMCSD_CMD24;	}	else	{		if(device->bit_width == 0)		{			_MMCSD_SetCmd(MMCSD_CMD25,addr,MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);			burst_len = 8;		}		else		{			_MMCSD_SetCmd(MMCSD_CMD25,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);			burst_len = 32;		}		g_mmcsd_cmd[device->port] = MMCSD_CMD25;	}	_MMCSD_StartClk(device->port);		ret = MMCSD_OK;	for( t=0; t<device->cur_num; t++)	{		counter = 0;#ifdef MMCSD_DMA_ENDIAN_ERR		p16 = (u16 *)device->tmp_pool[t];#else		p16 = (u16 *)device->buff_pool[t];#endif		while(ret == MMCSD_OK)		{			if(device->port == 1)				g_mmcsd_status = (mmcsdr_status_2);			else				g_mmcsd_status = (mmcsdr_status);			if((g_mmcsd_status&0x1043)==0)			{				continue;			}			j = 0xFF;			while(j--);//			TRACE("g_mmcsd_status = 0x%x",g_mmcsd_status);//			if(g_mmcsd_status&0x0003)			{				TRACE("7)ERROR!--, g_mmcsd_status = %lx",(unsigned long)g_mmcsd_status);				ret = MMCSD_ERROR;			}			else if((g_mmcsd_status&0x0040)!=0) // Buffer is empty			{//				TRACE("FIFO is empty!");				for(i = 0; i < burst_len; i++)				{					temp16 = (*p16);					temp32 = temp16;					if(device->port == 1)						mmcsdr_buffer_access_2 = temp32;					else						mmcsdr_buffer_access = temp32;											p16++;				}				counter += burst_len*2;			}			if(counter == device->blksize)			{				break;			}		}		if(ret!=MMCSD_OK)			break;	}	/*******************************************************	 * Write Done	 *******************************************************/	if(ret==MMCSD_OK)	{		while(1)		{			if(device->port == 1)				g_mmcsd_status = mmcsdr_status_2;			else				g_mmcsd_status = mmcsdr_status;			if(g_mmcsd_status&0x0007)			{				TRACE("8)ERROR! status = 0x%lx",(unsigned long)g_mmcsd_status);				ret = MMCSD_ERROR;				break;			}			else if((g_mmcsd_status&0x1000)!=0)			{				TRACE("9)Write Done! g_mmcsd_status = 0x%lx",(unsigned long)g_mmcsd_status);				ret = MMCSD_OK;				break;			}			TRACE("10)g_mmcsd_status = %lx",(unsigned long)g_mmcsd_status);		}	}	TRACE("Enable Intr...");	_MMCSD_Restore_Mask(int_mask,device->port);	g_mmcsd_cmd[device->port] = 0;	if(device->cur_num>1)	{		ret2=_MMCSD_NoDataCommand(MMCSD_CMD12,device->card_rca<<16,MMCSDB_R1,device->port);	}//	state =MMCSD_TRANSFER;//	mmcsd_check_status(device,&state);	mmcsd_free_buffer(device);	TRACE("15)return with ret = %lx,ret2 = %lx",(unsigned long)ret,(unsigned long)ret2);	return(ret|ret2);}MMCSD_STATUS mmcsd_dma_write_blks(MMCSD_Dev *device){	int i,timeleft;	u32 state,ret,ret2,int_mask = 0xFFFFFFFF;	u32 addr;	u32	status,counter;	if(device->cur_num == 0)	{		mmcsd_free_buffer(device);		return MMCSD_OK;	}	ret=ret2=MMCSD_OK;	g_selected_lock[device->port].device = device;	/**************************************************************	 * Check the Card Status	 **************************************************************/	//TRACE("Check Status");	state =MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		mmcsd_free_buffer(device);		FAILED("2)Check Error!");		return ret;	}	/**	 * End of Testing******************************************************************	 */	/**************************************************************	 * Set Block Length 	 **************************************************************/	i = 5;	while(i--)	{	//	TRACE("Set Block Length");		ret = _MMCSD_SetBlockLen(MMCSD_MINIMUM_BLK_SIZE,device->cur_num,device->port);		if(ret)		{			TRACE("3)Set Block Len, ret = 0x%lx,state=%lx",(unsigned long)ret,(unsigned long)state);			TRACE("4)Try again...%d",i);			state = MMCSD_TRANSFER;			mmcsd_check_status(device,&state);		}		else	//ret == SUCCESS!		{			break;		}	}	if(ret)	{		mmcsd_free_buffer(device);		FAILED("5)Set Blocked Len Failed!");		goto dma_write_end;	}		state = MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		mmcsd_free_buffer(device);		FAILED("Check Status failed.");		goto dma_write_end;	}	i = 10;	while(i--)	{	}	if(ret)	{		mmcsd_free_buffer(device);		FAILED("Set Bus Width Failed!");		goto dma_write_end;	}	/********************************************************************	 * Begin to write 	 *******************************************************************/	addr = device->addr;	//TRACE("6)address is 0x%lx(sector 0x%lx, %ld),blk number is %ld",	//		addr,addr/512,addr/512,device->cur_num);	/**************************************************************	 * Mask Interrupt	 **************************************************************/	//TRACE("Disable Interrupt");	_MMCSD_Mask_interrupt(0x78,&int_mask,device->port);	/*	 *  DMA Preparation	 */	/**************************************************************	 * Config DMA 	 **************************************************************///	TRACE("DMA Configuration");	ret = mmcsd_DmaStartTransfer(device,#ifdef MMCSD_DMA_ENDIAN_ERR				     device->tmp_pool[0],#else				     device->buff_pool[0],#endif				     MMCSD_MINIMUM_BLK_SIZE*(device->cur_num),				     MMCSD_WRITE,				     device->bit_width);	if(ret != MMCSD_OK)	{		FAILED("mmcsd_DmaStartTransfer failed");		goto dma_write_end;	}	/**************************************************************	 * Set Command 	 **************************************************************/	state =MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		FAILED("Check Status failed.");	}		//	TRACE("Set Command (24/25)");		_MMCSD_StopClk(device->port);	if(device->cur_num == 1)	{		if(device->bit_width == 0)		{			_MMCSD_SetCmd(MMCSD_CMD24,addr,MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);		}		else		{			_MMCSD_SetCmd(MMCSD_CMD24,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);		}	}	else	{		if(device->bit_width == 0)		{			_MMCSD_SetCmd(MMCSD_CMD25,addr,MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);		}		else		{			_MMCSD_SetCmd(MMCSD_CMD25,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,device->port);		}	}//	TRACE("Start Clk... Wait CMD Done.");	ret = MMCSD_OK;	_MMCSD_StartClk(device->port);	//if((ret=_MMCSD_irq_WaitUntil(MMCSD_CMD_DONE,MMCSD_CMD25,100))!=0)	if((ret=_MMCSD_WaitUntil(MMCSD_CMD_DONE,device->port))!=MMCSD_OK)	{		FAILED("WaitCMDDone ret 0x%lx",(unsigned long)ret);		goto dma_write_end;	}	if(device->port == 1)		g_mmcsd_status = mmcsdr_status_2;	else		g_mmcsd_status = mmcsdr_status;			if((g_mmcsd_status&0x40)==0)	{		FAILED("FIFO is not empty  0x%lx",(unsigned long)ret);		goto dma_write_end;	}	/**************************************************************	 * Enable DMA 	 **************************************************************///	TRACE("Enable DMA..");//	_MMCSD_StartClk();	g_mmcsd_cmd[device->port] = 0xFF;#ifdef CONFIG_ARCH_MX1ADS	enable_dma(device->dma_channel);#endif#ifdef CONFIG_ARCH_MX2ADS	mx_dma_start(device->dma_channel);#endif	timeleft = interruptible_sleep_on_timeout(&(device->select_wait),100);	if(!timeleft)	{		FAILED("write failed, Timeout!");	#ifdef CONFIG_ARCH_MX1ADS		disable_dma(device->dma_channel);	#endif	#ifdef CONFIG_ARCH_MX2ADS		_reg_DMA_CCR(device->dma_channel) &= 0xFFFFFFFE;		#endif		g_mmcsd_cmd[device->port] = 0x0;		ret = MMCSD_ERROR;		goto dma_write_end;	}#ifdef CONFIG_ARCH_MX1ADS	disable_dma(device->dma_channel);#endif#ifdef CONFIG_ARCH_MX2ADS	_reg_DMA_CCR(device->dma_channel) &= 0xFFFFFFFE;	#endif	g_mmcsd_cmd[device->port] = 0x0;//	TRACE("Waked up ");		status = device->result;//	TRACE("waked up! status = %lx",status);	counter = 0xFFFF;	while(counter--)	{		if(device->port == 1)			g_mmcsd_status = mmcsdr_status_2;		else				g_mmcsd_status = mmcsdr_status;				TRACE("g_mmcsd_status is 0x%0lX (for TRANS-DONE)",(unsigned long)g_mmcsd_status);		if((g_mmcsd_status&0x1007)==0)		{			mmcsd_delay(0xFFFF);			continue;		}		if(g_mmcsd_status&0x0007)		{			ret = MMCSD_ERROR;			FAILED("status is 0x%lx",(unsigned long)g_mmcsd_status);			goto dma_write_end;		}		ret = MMCSD_OK;		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -