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

📄 mmc_main.c

📁 给予mx21处理器的嵌入式系统的mmc卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(device->port == 0)		{			(device->dma).destAddr = 0x10013038;//sdhc1			(device->dma).request = 7;//sdhc1 				}		else		{			(device->dma).destAddr = 0x10014038;//for sdhc2 is 0x10014038			(device->dma).request = 0x6;//sdhc2 is 0x6;				}		if(is_4_bit)		{			(device->dma).burstLength = 0x0; //burst length 64		}		else		{			(device->dma).burstLength = 0x10; //burst len 16		}		mx_dma_set_config(device->dma_channel,&(device->dma));#endif	}					return MMCSD_OK;}/****************************************************************************** * Function Name: mmcsd_dma_handler * * Input:    * * Value Returned:      * * Description:  * 	 * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/void mmcsd_dma_isr(void *arg){	MMCSD_Dev *device;	device = g_selected_lock[0].device;	if(device == NULL)	{		TRACE("\nmmcsd_interrupt_handler: no device");		return;	}	g_mmcsd_status = (mmcsdr_status);	//TRACE("(status = 0x%x)",g_mmcsd_status);//	if(g_mmcsd_status&0x803)   // It should be here, but sometimes no 0x800 return.	{		device->result = g_mmcsd_status;		wake_up_interruptible(&(device->select_wait));	//	TRACE("Wake Up ...");	}}void mmcsd_dma_isr_1(void * arg){	MMCSD_Dev *device;	device = g_selected_lock[1].device;	if(device == NULL)	{		TRACE("\nmmcsd_interrupt_handler: no device");		return;	}	g_mmcsd_status = (mmcsdr_status_2);	//TRACE("(status = 0x%x)",g_mmcsd_status);//	if(g_mmcsd_status&0x803)   // It should be here, but sometimes no 0x800 return.	{		device->result = g_mmcsd_status;		wake_up_interruptible(&(device->select_wait));	//	TRACE("Wake Up ...");	}}void mmcsd_dma_err_isr(int error_type){	MMCSD_Dev *device;	device = g_selected_lock[0].device;	if(device == NULL)	{		TRACE("mmcsd_interrupt_handler: no device");		return;	}	g_mmcsd_status = (mmcsdr_status);	device->result = g_mmcsd_status;	TRACE("error_type = 0x%x",error_type);	wake_up_interruptible(&(device->select_wait));}void mmcsd_irq_handler_2(int irq,void * data, struct pt_regs * pt){	MMCSD_Dev *device;	mmcsdr_int_mask_2 |= 0x40;	device = g_selected_lock[1].device;	if(device == NULL)	{		return; 	}	g_mmcsd_status = (mmcsdr_status_2);	device->result = g_mmcsd_status;	if(g_mmcsd_cmd[device->port] != 0xFF)	{		wake_up_interruptible(&(device->select_wait));	}}void mmcsd_irq_handler(int irq,void * data, struct pt_regs * pt){	MMCSD_Dev *device;	mmcsdr_int_mask |= 0x40;	device = g_selected_lock[0].device;	if(device == NULL)	{		return; 	}//	TRACE("The Device not empty...");	g_mmcsd_status = (mmcsdr_status);	//TRACE("irq is called (%d), g_mmcsd_status = 0x%0X",g_mmcsd_cmd,g_mmcsd_status);	device->result = g_mmcsd_status;//	TRACE("Wake up the deice.. (status 0x%x)",device->result);	if(g_mmcsd_cmd[device->port] != 0xFF)	{		wake_up_interruptible(&(device->select_wait));	}}/****************************************************************************** * Function Name: mmcsd_tasklet * * Input:    * * Value Returned:      * * Description:  * 	 * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************//*void mmcsd_tasklet(){	MMCSD_Dev * device;	device = g_selected_lock.device;	if(device == NULL)	{		TRACE("\n mmcsd_tasklet: no device");		return;	}	switch (g_mmcsd_cmd)	{	case MMCSD_CMD17:	case MMCSD_CMD24:		disable_dma(MMCSD_DMA_CHANNEL);		device->result = get_dma_residue(MMCSD_DMA_CHANNEL);				free_dma(MMCSD_DMA_CHANNEL);		wake_up_interruptible(&(device->select_wait));		break;	default:		break;	}}*//****************************************************************************** * Function Name: mmcsd_ioctl * * Input: * 		inode	:	the pointer to MS driver-related inode. *		filep	:	the pointer to MS driver-related file structure.	 *		command	:	the command number. *		argument:	argument which depends on command. * * Value Returned: *		0	:	succeed *		1	:	fail * * Description: * 	This routine will implement driver-specific functions. * * Modification History: * 	30 DEC,2001,  Yiwei  Zhao *****************************************************************************/static int mmcsd_ioctl(struct inode *inode,			struct file *filp,			unsigned command,			unsigned long  argument){   	int num,ret;   	MMCSD_Dev *device;	MMCSD_PWD *pwd;	MMCSD_Blks blks;	u32 	addr;	TRACE("mmcsd_ioctl is called!");	num = MINOR(inode->i_rdev);	if(!filp)	{		TRACE("called without filp");		return -EIO;	}	if(num > g_mmcsd_num)	{		return -ENODEV;	}	device = &g_mmcsd_devices[num];    switch(command) {	case BLKFLSBUF:	case BLKRAGET:	        return blk_ioctl(inode->i_rdev, command, argument);	case BLKGETSIZE:		if (!argument) return -EINVAL; /* NULL pointer: not valid */		if (copy_to_user((long *) argument, &(device->dev_size), sizeof (long)))		{			return -EFAULT;		}		return 0;		case MMCSDSECTORSIZE:				if (!argument) return -EINVAL; /* NULL pointer: not valid */				if(copy_to_user((u16 *)argument, 				&(device->phy_sectorsize),				sizeof(u16)))		{			return -EFAULT;		}		return 0;	case MMCSDERASESECTOR:		if (!argument) return -EINVAL; /* NULL pointer: not valid */				if (copy_from_user(&blks, (MMCSD_Blks *)argument, sizeof (blks)))		{			return -EFAULT;		}		return(mmcsd_sector_erase(device, &blks));	case MMCSDPROTECT:		if (!argument) return -EINVAL; /* NULL pointer: not valid */		if (copy_from_user(&addr,(u32*)argument, sizeof(u32)))		{			return -EFAULT;		}		return(mmcsd_write_protect(device,addr,1));	case MMCSDCLEPROTECT:		if (!argument) return -EINVAL; /* NULL pointer: not valid */		if (copy_from_user(&addr,(u32*)argument, sizeof(u32)))		{			return -EFAULT;		}		return(mmcsd_write_protect(device,addr,0));	case MMCSDSETPW:	case MMCSDRESETPW:	case MMCSDLOCK:	case MMCSDUNLOCK:	case MMCSDFORCERASE: 		pwd = (MMCSD_PWD *)kmalloc((2+((MMCSD_PWD *)argument)->len),GFP_KERNEL|GFP_DMA);		if(pwd == NULL)		{			TRACE("\nmmcsd_ioctl: kmalloc error");			return 1;		}		if (copy_from_user(pwd,(MMCSD_PWD *)argument, sizeof((2+((MMCSD_PWD *) argument)->len))))		{			return -EFAULT;		}		ret = mmcsd_passwd_cmd(device,pwd);		kfree(pwd);		return(ret);	default:	        return blk_ioctl(inode->i_rdev, command, argument);	}    return 0; /* unknown command */}/****************************************************************************** * Function Name: mmcsd_write_protect * * Input: * 		device:	 	pointer to the specified device. * 		addr:		the address of the indicated group. * 		is_set:		TRUE, if set the write protection; False, clear * 				the write protection. * * Value Returned: *		0	:	succeed *		1	:	fail * * Description: * 	This routine will set/clear the write protection bit for addressed  * 	group. * * Modification History: * 	30 DEC,2001,  Yiwei  Zhao *****************************************************************************/static int mmcsd_write_protect(MMCSD_Dev *device,u32 addr, char is_set){	int ret = 0;#ifndef MMCSD_TEST	down_interruptible(&(device->sema));	g_selected_lock[device->port].device = device;#endif	if(mmcsd_is_writeprotection(device))	{		if(is_set)		{			ret = _MMCSD_SetWriteProt(addr);			if(ret)			{				TRACE("_MMCSD_SetWriteProt error");				goto write_protect_ret;			}		}		else		{			ret = _MMCSD_ClearWriteProt(addr);			if(ret)			{				TRACE("_MMCSD_ClearWriteProt error");				goto write_protect_ret;			}		}	}	else	{		INFO(" The card doesn't support the Write Protection Feature\n");		ret = MMCSD_ERROR;		goto write_protect_ret;	}write_protect_ret:#ifndef MMCSD_TEST	up(&(device->sema));#endif	return ret;}/****************************************************************************** * Function Name: mmcsd_passwd_cmd * * Input:	 * 		device: the device write to  * 		pwd:	pointer to MMCSD_PWD structure. * * Value Returned:  * 		0:	success. * 		1:	failure. * * Description:  * 	this routine will process passwd-related commands. * * Modification History: * 	30 DEC,2001, Initial version.  			Yiwei Zhao  *****************************************************************************/static int mmcsd_passwd_cmd(	MMCSD_Dev *device, 				MMCSD_PWD *pwd)	{	int ret,i;	u32	state,int_mask,temp32;	u16	temp16,*p16;	int burst_len,counter;	int total_len;		// it's different from pwd->len. the latter is the actural pwd len.				// total_len is the total size that will be write to FIFO.	if((device->ccc&MMCSD_CCC_LOCK) ==0)	{		FAILED("The card doesn't support the feature.");		return MMCSD_ERROR;	}		total_len = (pwd->len+2) + (pwd->len%2);	//********************************************************************	// Get Lock!!!!!!!!!!!!! 	//********************************************************************	#ifndef MMCSD_TEST	down_interruptible(&(device->sema));	g_selected_lock[device->port].device = device;#endif	//********************************************************************	// Check Status	//********************************************************************	state =MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		TRACE("check status failed.");		ret = MMCSD_ERROR;		goto passwd_failed;	}	/**************************************************************	 * Mask Interrupt	 **************************************************************/	TRACE("Disable Interrupt..");	_MMCSD_Mask_interrupt(0x7F,&int_mask,0);	/********************************************************************	 * Get the Lock for seclected device   	 *******************************************************************/#ifdef MMCSD_DMA_ENDIAN_ERR	_mmcsd_16_big_2_little((u8*)pwd, total_len);#endif	/********************************************************************	 * Define the block length 	 *******************************************************************/	ret = _MMCSD_SetBlockLen(2+pwd->len,1,device->port);	if(ret)		{		FAILED("SetBlockLen error");		ret = MMCSD_ERROR;		goto passwd_failed;	}	if(device->bit_width == 1)	{		ret = _MMCSD_SetBusWidth(device->card_rca,2,device->port);		if(ret)		{			FAILED("Set Bus Width failed.");			ret = MMCSD_ERROR;			goto passwd_failed;		}	}	else	{		ret = _MMCSD_SetBusWidth(device->card_rca,0,device->port);		if(ret)		{			FAILED("Set Bus Width failed.");			ret = MMCSD_ERROR;			goto passwd_failed;		}	}//	while(_MMCSD_IsRun())	_MMCSD_StopClk(0); 	//Ricky			/********************************************************************	 * Process Passwd command	 *******************************************************************/	counter = 0;	p16 = (u16 *)pwd;	TRACE("Begin Set Command..");	if(device->bit_width == 0)	{		_MMCSD_SetCmd(MMCSD_CMD42,0,MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,0);		burst_len = 8;	}	else	{		_MMCSD_SetCmd(MMCSD_CMD42,0,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1|MMCSDB_WRRD,0);		burst_len = 32;	}	g_mmcsd_cmd[device->port] = MMCSD_CMD42;	_MMCSD_StartClk(0);/*	if((ret=_MMCSD_WaitUntil(MMCSD_CMD_DONE))!=0)	{		FAILED("WaitCMDDone ret 0x%lx",ret);		goto passwd_failed;	}*/		ret = MMCSD_OK;	while(ret == MMCSD_OK)	{		TRACE("g_mmcsd_status is 0x%0X",g_mmcsd_status);		g_mmcsd_status = (mmcsdr_status);		if((g_mmcsd_status&0x1047)==0)		{			TRACE("g_mmcsd_status is 0x%0X",g_mmcsd_status);			continue;		}//		TRACE("g_mmcsd_status = 0x%x",g_mmcsd_status);		if(g_mmcsd_status&

⌨️ 快捷键说明

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