📄 mmci.c
字号:
mrq->data->error = 0; mrq->data->mrq = mrq; if (mrq->stop) { mrq->data->stop = mrq->stop; mrq->stop->error = 0; mrq->stop->mrq = mrq; } } host->data = mrq->data; host->size = mrq->data->blocks << mrq->data->blksz_bits; host->data_xfered = 0; mmci_init_sg(host, mrq->data); /*************WORKING******************/ /* * Map the current scatter buffer. 20*/ it_mmcsd_get_status(&cmd); it_mmcsd_clear_response_reg(&cmd); current_add = mrq->cmd->arg; no_of_blks = mrq->data->blocks; do{ unsigned long flags; unsigned int remain, len = 0; char *buffer = NULL; short *buffer_short = NULL; short stop_status = 0; short store_DMASEL; buffer = mmci_kmap_atomic(host, &flags) + host->sg_off; if (buffer == NULL) mmc_debug_msg ("NULL data Pointer\n"); remain = host->sg_ptr->length - host->sg_off; mmc_debug_msg ("WRITE_REMAIN : %d\n",remain); outw((remain/512),IO_MMC_NR_BLOCKS); buffer_short = (short*)buffer;#ifdef DMA_TRANSFER /* bring the sd/mmc controller to idle state */ reg = inw(IO_MMC_CONTROL); outw(reg | 0x03,IO_MMC_CONTROL); reg = inw(IO_MMC_CONTROL); outw(((inw(IO_MMC_CONTROL) | 0x10)&0xFBFF),IO_MMC_CONTROL); /* release idle state */ reg = inw(IO_MMC_CONTROL); outw(reg & 0xFFFC,IO_MMC_CONTROL); reg = inw(IO_MMC_CONTROL); outw(((0xDFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enabling DMA wmb(); outw((0x0002),IO_MMC_SD_DMA_TRIGGER);//DMA break wmb(); outw ((0x0003),IO_SDRAM_SDDMASEL); //printk("Started writing %x blocks from the address %x\n",no_of_blks,current_add); //outw(no_of_blks,IO_MMC_NR_BLOCKS); wmb(); store_DMASEL = inw (IO_SDRAM_SDDMASEL); rmb(); reg = store_DMASEL; //printk ("Value in IO_SDRAM_SDDMASEL : %x\n",reg); outw(((1 << 12) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//DIRECTION //outw((0x0400 | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enable word swap for Reading outw((0xF000),IO_MMC_SD_DMA_TIMEOUT); //2.4576ms //TIMEOUT wmb(); //outw((no_of_blks * 512),0x04B0); outw(remain,0x04B0);//DMA SIZE outw(((unsigned long)buffer_short & 0xFFFF),IO_MMC_SD_DMA_ADDR_LOW); wmb(); outw((((unsigned long)buffer_short >> 16) & 0xFFFF),IO_MMC_SD_DMA_ADDR_HI); wmb(); outw(((0x2000) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE); wmb();#endif marg = current_add; cmd1 = 25 |0x4000| 0x2000 |0x0800 | 0x0200 | 0x00; outw(marg & 0xFFFF,IO_MMC_ARG_LOW); outw((marg >> 16),IO_MMC_ARG_HI); outw(cmd1,IO_MMC_COMMAND); wmb(); write_count = 0;#ifndef DMA_TRANSFER temp = 0; it_mmcsd_get_status(&cmd); reg = cmd.status0; if ((cmd.status1 & 0x4)) { write_data = *buffer_short; buffer_short += 1; mmc_debug_msg_rw ("%x,",(write_data)& 0xFF); mmc_debug_msg_rw ("%x\t",((write_data >> 8) & 0xFF)); temp = (write_data & 0xFF00) >> 8; write_data = ((write_data & 0xFF) << 8) | temp; mmc_debug_msg ("***********in first condition**************\n"); outw(write_data,IO_MMC_TX_DATA); write_count += 1; } do { temp = 0; it_mmcsd_get_status(&cmd); reg = cmd.status0; if (reg & 0x0020) { mmc_debug_msg ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Write CRC error\n"); mmc_debug_msg ("STATUS0 :%x\tSTATUS1 :%x\n",cmd.status0,cmd.status1); host->data->error = MMC_ERR_BADCRC; goto end_write; } if ((cmd.status1 & 0x4)) { write_data = *buffer_short; mmc_debug_msg_rw ("%x,",(write_data)& 0xFF); mmc_debug_msg_rw ("%x\t",((write_data >> 8) & 0xFF)); temp = (write_data & 0xFF00) >> 8; write_data = ((write_data & 0xFF) << 8) | temp; buffer_short += 1; outw(write_data,IO_MMC_TX_DATA); wmb(); write_count += 1; } else{ if (cmd.status0 & 0x10){ mmc_debug_msg("Command Time OUT"); mmc_debug_msg ("S0 : %x\tS1 : %x\n",cmd.status0,cmd.status1); break; } } } while (!(reg &0x0001)); do{ it_mmcsd_get_status(&cmd); }while((!(cmd.status0 & 0x2)) && (cmd.status1 & 0x1));#else do { it_mmcsd_get_status(&cmd); if (cmd.status0 & MMC_INT_RSP_TIMEOUT){ host->data->error = 1; goto complete; } }while(!((cmd.status0 & 0x200)==0x200));//checking for respone of the command //it_mmcsd_print_status(&cmd); //printk ("Device Revision Number : %x\n",inw (IO_BUSC_REVR)); outw((0x0001),IO_MMC_SD_DMA_TRIGGER); wmb(); reg = 0; reg1 = 0; do { if (inw (IO_MMC_SD_DMA_STATUS1) & 0x1000){ reg = 0x1000; } it_mmcsd_get_status(&cmd); if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) |(cmd.status0 & MMC_INT_WRITE_CRC_ERROR)){ host->data->error = 1; outw((0x0002),IO_MMC_SD_DMA_TRIGGER); wmb(); goto complete; } }while((reg & 0x1000) && (!((cmd.status0 & 0x0100)==0x0100)));//Checking for DMA complete. write_count = 0; outw((0x0002),IO_MMC_SD_DMA_TRIGGER); wmb(); //printk("bytes read : %d\n",(read_count*2));#if 0 for(i=0;i< (512*no_of_blks);i++){ printk("%4c",*(buffer_short)); buffer_short += 1; }#endif#endif#ifndef DMA_TRANSFER len = (write_count*2);#else len = remain;#endif mmc_debug_msg ("len : %d\n",len); host->data_xfered += len; /* *Unmap the buffer. */ mmci_kunmap_atomic(host, &flags); host->sg_off += len; host->size -= len; remain -= len; /*************WORKING******************/ /*Stop command*/ it_mmcsd_get_status(&cmd); it_mmcsd_clear_response_reg(&cmd); marg = 0; cmd1 = 12 | 0x0200 | 0x0100 | 0x0080; outw(marg & 0xFFFF,IO_MMC_ARG_LOW); outw((marg >> 16),IO_MMC_ARG_HI); outw(cmd1,IO_MMC_COMMAND); stop_status = 0; do { it_mmcsd_get_status(&cmd); if (cmd.status0 & 0x4) stop_status |= cmd.status0; if (cmd.status0 & 0x2) stop_status |= cmd.status0; if (cmd.status0 & MMC_INT_RSP_TIMEOUT){ host->data->error = 1; goto complete; } }while( !((stop_status& 0x6)==6));//checking for busy state and response of the command if (remain){ break; } if (!mmci_next_sg(host)){ it_mmcsd_get_status(&cmd); break; } current_add += len; }while(1); mrq->data->bytes_xfered = host->data_xfered; mmc_debug_msg ("mrq->data->bytes_xfered : %d\n",mrq->data->bytes_xfered);complete: /* enable clock */ reg = mmc_inw(IO_MMC_MEM_CLK_CONTROL); mmc_outw(reg | 0x0100, IO_MMC_MEM_CLK_CONTROL); local_irq_enable(); enable_interrupt(); spin_unlock(&host->lock); host->data = NULL; return 0;}int read_from_card(struct mmc_host *mmc,struct mmc_request *mrq){ u32 current_add; u16 no_of_blks; u32 marg; u16 cmd1,reg; int read_count; struct mmc_command cmd; struct mmci_host *host = mmc_priv(mmc); spin_lock(&host->lock); disable_interrupt(); local_irq_disable(); /* disable clock */ reg = inw(IO_MMC_MEM_CLK_CONTROL); outw(reg & 0xFEFF, IO_MMC_MEM_CLK_CONTROL); rmb(); mrq->cmd->error = 0; mrq->cmd->mrq = mrq; host->cmd = mrq->cmd; if (mrq->data) { mrq->cmd->data = mrq->data; mrq->data->error = 0; mrq->data->mrq = mrq; if (mrq->stop) { mrq->data->stop = mrq->stop; mrq->stop->error = 0; mrq->stop->mrq = mrq; } } host->data = mrq->data; host->size = mrq->data->blocks << mrq->data->blksz_bits; host->data_xfered = 0; mmci_init_sg(host, mrq->data); /*************WORKING******************/ /* * Map the current scatter buffer. 20*/ it_mmcsd_get_status(&cmd); it_mmcsd_clear_response_reg(&cmd); current_add = mrq->cmd->arg; no_of_blks = mrq->data->blocks;// * host->sg_len; //To read more than segment do{ unsigned long flags; unsigned int remain, len = 0; char *buffer; char *buffer_short = NULL; short store_DMASEL = 0; buffer = mmci_kmap_atomic(host, &flags) + host->sg_off; if (buffer == NULL) mmc_debug_msg ("NULL data Pointer\n"); remain = host->sg_ptr->length - host->sg_off; mmc_debug_msg (">>>>>>>>>>>>REMAIN : %d\n",remain); outw((remain/512),IO_MMC_NR_BLOCKS); buffer_short = buffer;#ifdef DMA_TRANSFER /* bring the sd/mmc controller to idle state */ reg = inw(IO_MMC_CONTROL); outw(reg | 0x03,IO_MMC_CONTROL); reg = inw(IO_MMC_CONTROL); outw(((inw(IO_MMC_CONTROL) | 0x10)&0xFDFF),IO_MMC_CONTROL); /* release idle state */ reg = inw(IO_MMC_CONTROL); outw(reg & 0xFFFC,IO_MMC_CONTROL); reg = inw(IO_MMC_CONTROL); outw(((0xDFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE); wmb(); outw((0x0002),IO_MMC_SD_DMA_TRIGGER); wmb(); outw ((0x0003),IO_SDRAM_SDDMASEL); //printk("Started Reading %x blocks from the address %x\n",no_of_blks,current_add); //outw(no_of_blks,IO_MMC_NR_BLOCKS); wmb(); store_DMASEL = inw (IO_SDRAM_SDDMASEL); rmb(); reg = store_DMASEL; //printk ("Value in IO_SDRAM_SDDMASEL : %x\n",reg); outw(((0xEFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE); //outw((0x0400 | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enable word swap for Reading outw((0xF000),IO_MMC_SD_DMA_TIMEOUT); //2.4576ms wmb(); //outw((no_of_blks * 512),0x04B0); outw(remain,0x04B0);//DMA SIZE outw(((unsigned long)buffer_short & 0xFFFF),IO_MMC_SD_DMA_ADDR_LOW); wmb(); outw((((unsigned long)buffer_short >> 16) & 0xFFFF),IO_MMC_SD_DMA_ADDR_HI); wmb(); outw(((0x2000) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE); wmb();#endif marg = current_add; cmd1 = 18 | 0x0200 | 0x4000 | 0x2000 | 0x0080 | 0x0000; outw(marg & 0xFFFF,IO_MMC_ARG_LOW); outw((marg >> 16),IO_MMC_ARG_HI); outw(cmd1,IO_MMC_COMMAND); do { it_mmcsd_get_status(&cmd); if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) | (cmd.status0 & MMC_INT_RSP_CRC_ERROR)){ host->data->error = 1; goto complete_read; } }while( !((cmd.status0 & 0x4)==4));//checking for busy state and respone of the read command read_count = 0;#ifndef DMA_TRANSFER do{ it_mmcsd_get_status(&cmd); reg = cmd.status0; if (reg & 0x0040) { mmc_debug_msg ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Read CRC error\n"); mmc_debug_msg ("STATUS0 :%x\tSTATUS1 :%x\n",cmd.status0,cmd.status1); break; } if ((cmd.status1 & 0x8)) { temp_data = inw (IO_MMC_RX_DATA); mmc_debug_msg_rw ("%x\t",temp_data); *buffer_short = (temp_data >> 8) & 0xFF; buffer_short = buffer_short + 1; *buffer_short = temp_data & 0xFF; buffer_short = buffer_short + 1; read_count++; } else if (cmd.status0 & 0x10){ mmc_debug_msg("Command Time OUT"); break; } } while (!(reg &0x0001)); temp_data = inw (IO_MMC_RX_DATA); mmc_debug_msg_rw ("%x\t",temp_data); *buffer_short = (temp_data >> 8) & 0xFF; buffer_short = buffer_short + 1; *buffer_short = temp_data & 0xFF; buffer_short = buffer_short + 1; read_count++; do{ it_mmcsd_get_status(&cmd); }while((cmd.status1 & 0x1)); if(reg &1) { int temp = inw(IO_MMC_NR_BLOCKS_COUNT); mmc_debug_msg ("No of blocks remaining to be transferd :%d\n",temp); }#else do { it_mmcsd_get_status(&cmd); if (cmd.status0 & MMC_INT_RSP_TIMEOUT){ host->data->error = 1; goto complete_read; } }while(!((cmd.status0 & 0x400)==0x400));//checking for respone of the command //it_mmcsd_print_status(&cmd); //printk ("Device Revision Number : %x\n",inw (IO_BUSC_REVR)); outw((0x0001),IO_MMC_SD_DMA_TRIGGER); wmb();#if 0 do { reg = inw (IO_MMC_SD_DMA_STATUS1); rmb(); }while( (reg & 0x1000));//Checking for DMA complete. read_count = 0; do { it_mmcsd_get_status(&cmd); }while( !((cmd.status0 & 0x0100)==0x0100));//Checking for DMA Done#else reg = 0; do { if (inw (IO_MMC_SD_DMA_STATUS1) & 0x1000){ reg = 0x1000; } it_mmcsd_get_status(&cmd); if ((cmd.status0 & MMC_INT_READ_TIMEOUT) |(cmd.status0 & MMC_INT_READ_CRC_ERROR)){ host->data->error = 1; outw((0x0002),IO_MMC_SD_DMA_TRIGGER); wmb(); goto complete_read; } }while((reg & 0x1000) && (!((cmd.status0 & 0x0100)==0x0100)));//Checking for DMA complete.#endif outw((0x0002),IO_MMC_SD_DMA_TRIGGER); wmb(); //printk("bytes read : %d\n",(read_count*2));#if 0 for(i=0;i< (512*no_of_blks);i++){ printk("%4c",*(buffer_short)); buffer_short += 1; }#endif#endif#ifndef DMA_TRANSFER len = buffer_short - buffer;#else len = remain;#endif mmc_debug_msg ("len : %d\n",len); host->data_xfered += len; /* * Unmap the buffer. */ mmci_kunmap_atomic(host, &flags); buffer = NULL; buffer_short = NULL ; host->sg_off += len; host->size -= len; remain -= len; /*************WORKING******************/ /*Stop command*/ it_mmcsd_get_status(&cmd); it_mmcsd_clear_response_reg(&cmd); marg = 0; cmd1 = 12 | 0x0200 | 0x0100 | 0x0080; outw(marg & 0xFFFF,IO_MMC_ARG_LOW); outw((marg >> 16),IO_MMC_ARG_HI); outw(cmd1,IO_MMC_COMMAND); do { it_mmcsd_get_status(&cmd); mmc_debug_msg("S0 : %x\t S1 : %x\n",cmd.status0,cmd.status1); if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) | (cmd.status0 & MMC_INT_RSP_CRC_ERROR)){ host->data->error = 1; goto complete_read; } }while( !((cmd.status0 & 0x4)==4));//checking for busy state and respone of the command if (remain){ mmc_debug_msg ("REMAIN AFTER READ : %d\n",remain); } if (!mmci_next_sg(host)){ it_mmcsd_get_status(&cmd); break; } current_add += len; }while(1); mrq->data->bytes_xfered = host->data_xfered; mmc_debug_msg ("mrq->data->bytes_xfered : %d\n",mrq->data->bytes_xfered);complete_read:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -