📄 mmc_main.c
字号:
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 + -