OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mmc/] [host/] [mmc_ocores.c] - Diff between revs 81 and 82

Show entire file | Details | Blame | View Log

Rev 81 Rev 82
Line 71... Line 71...
                unsigned int data_int_status;
                unsigned int data_int_status;
        } registers;
        } registers;
        int clock;
        int clock;
 
 
        /* DMA buffer used for transmitting */
        /* DMA buffer used for transmitting */
        unsigned int* buffer;
 
        dma_addr_t physical_address;
 
        unsigned int total_length;
        unsigned int total_length;
        unsigned int            dma_len;
        unsigned int            dma_len;
        /* Latest in the scatterlist that has been enabled for transfer, but not freed */
 
        int in_use_index;
 
 
 
        /* Latest in the scatterlist that has been enabled for transfer */
 
        int transfer_index;
        int transfer_index;
 
 
        int free_tx_bd;
        int free_tx_bd;
        int free_rx_bd;
        int free_rx_bd;
 
        /* Latest in the scatterlist that has been enabled for transfer, but not freed */
 
        int in_use_index;
};
};
 
 
struct ocores_host *oc_host;
 
 
 
static void ocores_tasklet_finish_cmd(unsigned long param);
static void ocores_tasklet_finish_cmd(unsigned long param);
static void ocores_tasklet_finish_data(unsigned long param);
static void ocores_tasklet_finish_data(unsigned long param);
 
 
static inline void CMD_IRQ_ON(struct ocores_host *host, u32 mask)
static inline void CMD_IRQ_ON(struct ocores_host *host, u32 mask)
Line 105... Line 104...
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
}
}
 
 
static inline void DAT_IRQ_ON(struct ocores_host *host, u32 mask)
static inline void DAT_IRQ_ON(struct ocores_host *host, u32 mask)
{
{
 
 
 
 
        u32 val = readl(host->base  + SD_BD_ISER);
        u32 val = readl(host->base  + SD_BD_ISER);
        val |= mask;
        val |= mask;
        writel (val, host->base  + SD_BD_ISER);
        writel (mask, host->base  + SD_BD_ISER);
 
 
 
 
 
 
}
}
 
 
static inline void DAT_IRQ_OFF(struct ocores_host *host, u32 mask)
static inline void DAT_IRQ_OFF(struct ocores_host *host, u32 mask)
{
{
        u32 val = readl(host->base  + SD_BD_ISER);
        u32 val = readl(host->base  + SD_BD_ISER);
        val  &= ~mask;
        val  &= ~mask;
        writel (val, host->base  + SD_BD_ISER);
        writel (val, host->base  + SD_BD_ISER);
}
}
 
 
 
 
static void ocores_pre_dma_read(struct ocores_host *host)
static void ocores_pre_dma(struct ocores_host *host)
{
{
        int i,j;
        unsigned int i,j;
        int off_scal;
        unsigned int off_scal;
        struct scatterlist *sg;
        struct scatterlist *sg;
        struct mmc_command *cmd;
        struct mmc_command *cmd;
        struct mmc_data *data;
        struct mmc_data *data;
 
        unsigned long flags;
 
 
        off_scal=512;
        off_scal=512;
        if (host->mmc->card!= NULL){
        if (host->mmc->card!= NULL){
 
 
                if (mmc_card_blockaddr(host->mmc->card))
                if (mmc_card_blockaddr(host->mmc->card))
                        off_scal=1;
                        off_scal=1;
                else
                else
                        off_scal=512;
                        off_scal=512;
        }
        }
        printk("pre dma read off %d\n", off_scal);
        pr_debug("Pre block_offset %d\n", off_scal);
 
 
        cmd = host->cmd;
        cmd = host->cmd;
        if (!cmd) {
        if (!cmd) {
                pr_debug("no command\n");
                pr_debug("no command\n");
                return;
                return;
Line 148... Line 153...
                pr_debug("no data\n");
                pr_debug("no data\n");
                return;
                return;
        }
        }
 
 
        /* Setup the next transfer */
        /* Setup the next transfer */
        pr_debug("Using transfer index %d\n", host->transfer_index);
 
 
 
        sg = &data->sg[host->transfer_index++];
        sg = &data->sg[host->transfer_index++];
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
 
        pr_debug("sg = %p\n", sg);
 
        printk("sg = %p\n", sg);
 
 
 
 
 
 
        if (data->flags & MMC_DATA_READ)
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_FROM_DEVICE);
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_FROM_DEVICE);
        printk(KERN_ALERT "dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
        else
 
                host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_TO_DEVICE);
 
        pr_debug(KERN_ALERT "Dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
 
        printk(KERN_ALERT "Dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
 
 
        for (i = 0; i < host->dma_len; i++) {
        for (i = 0; i < host->dma_len; i++) {
                unsigned int length = sg_dma_len(&data->sg[i]);
                unsigned int length = sg_dma_len(&data->sg[i]);
 
 
                if (length >= 512)
                if (length >= 512)
                        length /=512;
                        length /=512;
                else
                else
                        length = 1;
                        length = 1;
 
 
                printk(KERN_ALERT "DMA LEN %d\n", length);
 
                //XXX:512 SD 1.0 card only.
                //XXX:512 SD 1.0 card only.
 
                if (data->flags & MMC_DATA_READ){
                for (j = 0; j< length;j++) {
                for (j = 0; j< length;j++) {
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
 
                        printk(KERN_ALERT "dma address = %d, length = %d, sg_dma_len %d\n", (sg_dma_address(&data->sg[i])+512*j), length, host->dma_len);
 
 
 
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_RX);
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_RX);
                        wmb();
                        wmb();
                        writel(cmd->arg+off_scal*j, host->base + BD_RX);
                        writel(cmd->arg+off_scal*j, host->base + BD_RX);
 
 
                }
                }
 
                        DAT_IRQ_ON (host,(TRE|CMDE|FIFOE|MRC|TRS));
        }
        }
 
                else{
 
 
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
                        for (j = 0; j< length;j++) {
        pr_debug("pre dma read done\n");
 
}
 
static void ocores_pre_dma_write(struct ocores_host *host)
 
{
 
        int i,j;
 
        int off_scal;
 
        struct scatterlist *sg;
 
        struct mmc_command *cmd;
 
        struct mmc_data *data;
 
 
 
        off_scal=512;
 
        if (host->mmc->card!= NULL){
 
 
 
                if (mmc_card_blockaddr(host->mmc->card))
                                writel((sg_dma_address(&data->sg[i])+ 512*j), host->base + BD_TX);
                        off_scal=1;
                                wmb();
                else
                                writel(cmd->arg+off_scal*j, host->base + BD_TX);
                        off_scal=512;
 
        }
 
        printk("pre dma write off %d\n", off_scal);
 
 
 
        cmd = host->cmd;
 
        if (!cmd) {
 
                pr_debug("no command\n");
 
                return;
 
        }
 
        data = cmd->data;
 
        if (!data) {
 
                pr_debug("no data\n");
 
                return;
 
        }
        }
 
 
        /* Setup the next transfer */
 
        pr_debug("Using transfer index %d\n", host->transfer_index);
 
 
 
        sg = &data->sg[host->transfer_index++];
 
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
 
        pr_debug("sg = %p\n", sg);
 
        printk("sg = %p\n", sg);
 
 
 
 
                        DAT_IRQ_ON (host,(TRE|CMDE|FIFOE|MRC|TRS));
 
                        pr_debug("pre dma write done\n");
 
                }
 
 
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_TO_DEVICE);
 
        printk(KERN_ALERT "dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
 
        for (i = 0; i < host->dma_len; i++) {
 
                unsigned int length = sg_dma_len(&data->sg[i]);
 
 
 
                if (length >= 512)
        }
                        length /=512;
 
                else
 
                        length = 1;
 
 
 
                printk(KERN_ALERT "DMA LEN %d\n", length);
 
                //XXX:512 SD 1.0 card only.
 
                for (j = 0; j< length;j++) {
 
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
 
                        printk(KERN_ALERT "dma address = %d, length = %d, sg_dma_len %d\n", (sg_dma_address(&data->sg[i])+512*j), length, host->dma_len);
 
 
 
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_TX);
 
                        wmb();
 
                        writel(cmd->arg+off_scal*j, host->base + BD_TX);
 
 
 
                }
                }
 
 
        }
 
 
 
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
 
        pr_debug("pre dma read done\n");
 
}
 
 
 
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
{
{
        unsigned int cmd_arg, cmd_command=0;
        unsigned int cmd_arg, cmd_command=0;
 
 
        struct mmc_data *data = cmd->data;
        struct mmc_data *data = cmd->data;
        //WARN_ON(host->cmd != NULL);
        //WARN_ON(host->cmd != NULL);
        host->cmd = cmd;
        host->cmd = cmd;
 
 
        //XXX:opcode == 51 not supported by hardware, hack here     
        //XXX:opcode == 51 not supported by hardware, hack here     
        if (data && ( cmd->opcode != 51)) {
        if (data && ( cmd->opcode != 51)&& ( cmd->opcode != 12)) {
                if ( data->blksz & 0x3 ) {
                if ( data->blksz & 0x3 ) {
                        pr_debug("Unsupported block size\n");
                        pr_debug("Unsupported block size\n");
                        cmd->error = -EINVAL;
                        cmd->error = -EINVAL;
                        mmc_request_done(host->mmc, host->mrq);
                        mmc_request_done(host->mmc, host->mrq);
                        return;
                        return;
Line 271... Line 227...
                data->bytes_xfered = 0;
                data->bytes_xfered = 0;
                host->transfer_index = 0;
                host->transfer_index = 0;
                host->in_use_index = 0;
                host->in_use_index = 0;
 
 
                if (data->flags & MMC_DATA_READ){  //Handle a read
                if (data->flags & MMC_DATA_READ){  //Handle a read
                        printk(KERN_ALERT "%s: Data read\n", __FUNCTION__);
                        pr_debug(KERN_ALERT "%s: Data read dat Len %u\n", __FUNCTION__,host->total_length);
                        host->buffer = NULL;
 
                        host->total_length = 0;
 
                        ocores_pre_dma_read(host); //Set up BD
 
 
 
                }
 
                else if (data->flags & MMC_DATA_WRITE){ //Handle write
 
                        printk(KERN_ALERT "%s: Data write\n", __FUNCTION__);    //cmdr |= AT91_MCI_TRCMD_START;
 
                        /*host->buffer = dma_alloc_coherent(NULL,
 
                                        host->total_length,
 
                                        &host->physical_address, GFP_KERNEL); */
 
                        host->total_length = 0;
                        host->total_length = 0;
                        ocores_pre_dma_write(host); //Set up BD
                        ocores_pre_dma(host); //Set up BD
 
 
                }
                }
 
                else if (data->flags & MMC_DATA_WRITE){ //Handle write
 
                                //cmdr |= AT91_MCI_TRCMD_START;
 
 
 
                        host->total_length = data->sg->length;
 
                        pr_debug(KERN_ALERT "%s: Data write dat Len %u\n", __FUNCTION__,host->total_length);
 
 
                if (data->flags & MMC_DATA_STREAM)
                        ocores_pre_dma(host); //Set up BD
                        printk(KERN_ALERT "%s: MMC_DATA_STREAM\n", __FUNCTION__);
 
                if (data->blocks > 1)
 
                        printk(KERN_ALERT "%s: data->blocks %d  > 1 \n", __FUNCTION__, data->blocks);
 
 
 
 
 
                        /*
 
                        host->total_length = block_length * blocks;
 
                        host->buffer = dma_alloc_coherent(NULL,
 
                                        host->total_length,
 
                                        &host->physical_address, GFP_KERNEL);
 
 
 
                        at91_mci_sg_to_dma(host, data);
 
 
 
                        pr_debug("Transmitting %d bytes\n", host->total_length);
 
 
 
                        at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
 
                        at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
 
                        ier = AT91_MCI_CMDRDY; */
 
 
 
 
 
 
                }
 
 
 
 
        }
        }
        else{
        else{
                        //Set up command
                        //Set up command
Line 348... Line 281...
                 //Send Command
                 //Send Command
                CMD_IRQ_ON (host,(ECC|EEI));
                CMD_IRQ_ON (host,(ECC|EEI));
                writel(cmd_command, host->base + SD_COMMAND);
                writel(cmd_command, host->base + SD_COMMAND);
                wmb();
                wmb();
                writel(cmd_arg, host->base + SD_ARG);
                writel(cmd_arg, host->base + SD_ARG);
                printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
                //printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
                printk(KERN_ALERT "%s: cmd_command   = %08x\n", __FUNCTION__, cmd_command);
                //printk(KERN_ALERT "%s: cmd_command   = %08x\n", __FUNCTION__, cmd_command);
 
 
        }
        }
 
 
 
 
        oc_host=host;
 
 
 
 
 
}
}
 
 
static void ocores_process_next(struct ocores_host *host)
static void ocores_process_next(struct ocores_host *host)
{
{
        host->word_cnt=0;
        host->word_cnt=0;
 
 
        if (!(host->flags & FL_SENT_COMMAND)) {
        if (!(host->flags & FL_SENT_COMMAND)) {
                host->flags |= FL_SENT_COMMAND;
                host->flags |= FL_SENT_COMMAND;
                ocores_start_cmd(host, host->mrq->cmd);
                ocores_start_cmd(host, host->mrq->cmd);
        }
        }
        else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) {
        else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) {
Line 376... Line 307...
 
 
static void ocores_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void ocores_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
{
        struct ocores_host *host = mmc_priv(mmc);
        struct ocores_host *host = mmc_priv(mmc);
 
 
        //unsigned int cmdr, mr;
 
 
 
        printk(KERN_ALERT "%s: mrq->cmd->opcode = %08x\n", __FUNCTION__, mrq->cmd->opcode);
 
        printk(KERN_ALERT "%s: mrq->cmd->arg    = %08x\n", __FUNCTION__, mrq->cmd->arg);
 
 
 
        //WARN_ON(host->mrq != NULL);
 
 
 
        host->mrq = mrq;
        host->mrq = mrq;
        host->flags = 0;
        host->flags = 0;
 
 
        ocores_process_next(host);
        ocores_process_next(host);
 
 
 
 
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
        //printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
}
}
 
 
 
 
 
 
static int ocores_get_ro(struct mmc_host *mmc)
static int ocores_get_ro(struct mmc_host *mmc)
Line 471... Line 395...
 
 
static irqreturn_t ocores_irq_dat(int irq, void *devid)
static irqreturn_t ocores_irq_dat(int irq, void *devid)
{
{
         struct ocores_host *host = (struct ocores_host *) devid;
         struct ocores_host *host = (struct ocores_host *) devid;
 
 
         disable_irq(host->irq_dat);
         //disable_irq(host->irq_dat);
 
 
         printk(KERN_ALERT "%s: DAT IRQ START***** Normal In  = %08x\n", __FUNCTION__, readl(host->base + SD_BD_ISR));
 
 
 
         host->registers.data_int_status  = readl(host->base + SD_BD_ISR);
         host->registers.data_int_status  = readl(host->base + SD_BD_ISR);
 
 
         writel(0,host->base + SD_BD_ISR);
         writel(0,host->base + SD_BD_ISR);
 
 
         tasklet_schedule(&host->finish_data);
         tasklet_schedule(&host->finish_data);
 
 
         enable_irq(host->irq_dat);
         //enable_irq(host->irq_dat);
 
 
         return IRQ_HANDLED;
         return IRQ_HANDLED;
 
 
 
 
 
 
Line 528... Line 449...
        mmc->ops = &ocores_ops;
        mmc->ops = &ocores_ops;
 
 
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
        mmc->caps = MMC_CAP_4_BIT_DATA;
        mmc->caps = MMC_CAP_4_BIT_DATA;
        mmc->f_min = 700000;  //SYS_CLK  60; 0.7 Mhz
        mmc->f_min = 700000;  //SYS_CLK  60; 0.7 Mhz
        mmc->f_max = 4166666;  //SYS_CLK;   4.166 666 mhz
        mmc->f_max = 6166666;  //SYS_CLK;   4.166 666 mhz
 
 
        mmc->max_blk_count =  8;//8; //XXX: 8
        mmc->max_blk_count =  4;//8; //XXX: 8
        mmc->max_hw_segs = 1;
        mmc->max_hw_segs = 2;
        mmc->max_blk_size = MMCOC_MAX_BLOCK_SIZE;
        mmc->max_blk_size = MMCOC_MAX_BLOCK_SIZE;
        //mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
        //mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
 
 
 
 
        mmc->max_seg_size = PAGE_SIZE;
        mmc->max_seg_size = PAGE_SIZE;
Line 605... Line 526...
        enable_irq(host->irq_cmd);
        enable_irq(host->irq_cmd);
        enable_irq(host->irq_dat);
        enable_irq(host->irq_dat);
        printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base);
        printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base);
        printk(KERN_ALERT "%s: SD_BLOCK = %08x\n", __FUNCTION__, readl(host->base + SD_BLOCK));
        printk(KERN_ALERT "%s: SD_BLOCK = %08x\n", __FUNCTION__, readl(host->base + SD_BLOCK));
        printk(KERN_ALERT "%s: host->pdata->ocr_mask = %08x\n", __FUNCTION__, host->pdata->ocr_mask);
        printk(KERN_ALERT "%s: host->pdata->ocr_mask = %08x\n", __FUNCTION__, host->pdata->ocr_mask);
        oc_host=host;
 
        mmc_add_host(mmc);
        mmc_add_host(mmc);
 
 
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
 
 
        return 0;
        return 0;
Line 631... Line 552...
        struct mmc_data *data;
        struct mmc_data *data;
        struct scatterlist *sg;
        struct scatterlist *sg;
        data = host->cmd->data;
        data = host->cmd->data;
        sg = &data->sg[0];
        sg = &data->sg[0];
 
 
        printk(KERN_ALERT " CMD TASKLET RUNNS************\n");
        //printk(KERN_ALERT " CMD TASKLET RUNNS************\n");
        //Check For Transmissions errors
        //Check For Transmissions errors
        if ((host->registers.normal_int_status & EI) == EI)
        if ((host->registers.normal_int_status & EI) == EI)
        {
        {
                printk(KERN_ALERT "TRANSMISSION ERROR DETECTED");
                printk(KERN_ALERT "TRANSMISSION ERROR DETECTED");
                switch ( host->registers.error_int_status )
                switch ( host->registers.error_int_status )
                {
                {
                case (CTE):
                case (CTE):
                        pr_debug("Card took too long to respond\n");
                        pr_debug("Card took too long to respond\n");
                        host->mrq->cmd->error = -ETIMEDOUT ;
                        host->mrq->cmd->error = -ETIMEDOUT ;
 
                        if (host->mrq->stop)
 
                                host->mrq->stop->error = -ETIMEDOUT ;
                        break;
                        break;
                case (CCRC  ):
                case (CCRC  ):
                        pr_debug(" CRC  problem with the received or sent data\n");
                        pr_debug(" CRC  problem with the received or sent data\n");
                        host->mrq->cmd->error = -EILSEQ;
                        host->mrq->cmd->error = -EILSEQ;
 
                        if (host->mrq->stop)
 
                                host->mrq->stop->error = -EILSEQ ;
                        break;
                        break;
                case (CIE  ):
                case (CIE  ):
                        pr_debug("Index problem with the received or sent data\n");
                        pr_debug("Index problem with the received or sent data\n");
                        host->mrq->cmd->error = -EILSEQ;
                        host->mrq->cmd->error = -EILSEQ;
 
                        if (host->mrq->stop)
 
                                host->mrq->stop->error = -EILSEQ ;
                        break;
                        break;
                }
                }
 
 
                mmc_request_done(host->mmc, host->mrq);
                mmc_request_done(host->mmc, host->mrq);
        }
        }
Line 706... Line 633...
                        }
                        }
                }
                }
                else  //Short response
                else  //Short response
                {
                {
                        host->mrq->cmd->error = 0 ;
                        host->mrq->cmd->error = 0 ;
 
 
 
                        if (host->mrq->stop)
 
                                host->mrq->stop->resp[0] = readl(host->base + SD_RESP1);
 
                        else
                        host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
                        host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
                        printk(KERN_ALERT "Short Response CMD RSP * = %08x\n", host->mrq->cmd->resp[0]);
                        //printk(KERN_ALERT "Short Response CMD RSP * = %08x\n", host->mrq->cmd->resp[0]);
                        mmc_request_done(host->mmc, host->mrq);
                        mmc_request_done(host->mmc, host->mrq);
                }
                }
        }
        }
 
 
}
}
Line 725... Line 656...
        int free_bd,i;
        int free_bd,i;
        int *adr;
        int *adr;
        data = host->cmd->data;
        data = host->cmd->data;
        sg = &data->sg[0]; //XXX:O Change to dynamic later?
        sg = &data->sg[0]; //XXX:O Change to dynamic later?
 
 
        printk(KERN_ALERT " DATA TASKLET RUNNS************\n");
 
 
 
        //IF read operation
        //IF read operation
 
 
        if ((host->registers.data_int_status & TRS) == TRS){
        if ((host->registers.data_int_status & TRS) == TRS){
                if (data->flags & MMC_DATA_READ){
                if (data->flags & MMC_DATA_READ){
                        free_bd=readl( host->base + BD_STATUS );
                        free_bd=readl( host->base + BD_STATUS );
                        free_bd=(free_bd&0xff00)>>8;
                        free_bd=(free_bd&0xff00)>>8;
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
                        //printk(KERN_ALERT " DATA READ TASKLET RUNNS*** Free BD %d\n", free_bd);
                        if (free_bd == host->free_tx_bd) {
                        if (free_bd == host->free_rx_bd) {
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_FROM_DEVICE);
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_FROM_DEVICE);
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
 
 
 
                                DAT_IRQ_OFF (host,(TRE|CMDE|FIFOE|MRC|TRS));
                                data->bytes_xfered = sg->length;
                                data->bytes_xfered = sg->length;
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
 
 
                                if (host->mrq->stop)
 
                                        host->mrq->stop->resp[0] = readl(host->base + SD_RESP1);
 
 
 
 
                                mmc_request_done(host->mmc, host->mrq);
                                mmc_request_done(host->mmc, host->mrq);
 
 
                        }
                        }
                } else if (data->flags & MMC_DATA_WRITE){
                } else if (data->flags & MMC_DATA_WRITE){
                        free_bd=readl( host->base + BD_STATUS );
                        free_bd=readl( host->base + BD_STATUS );
                        free_bd=(free_bd&0x00FF);
                        free_bd=(free_bd&0x00FF);
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
                        //printk(KERN_ALERT " DATA WRITE TASKLET RUNNS*** Free BD %d\n", free_bd);
                        if (free_bd == host->free_tx_bd) {
                        if (free_bd == host->free_tx_bd) {
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_TO_DEVICE);
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_TO_DEVICE);
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
 
 
 
                                DAT_IRQ_OFF (host,(TRE|CMDE|FIFOE|MRC|TRS));
                                data->bytes_xfered = sg->length;
                                data->bytes_xfered = sg->length;
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
 
 
 
 
                                if (host->mrq->stop)
 
                                        host->mrq->stop->resp[0] = readl(host->base + SD_RESP1);
 
 
 
 
                                mmc_request_done(host->mmc, host->mrq);
                                mmc_request_done(host->mmc, host->mrq);
 
 
                        }
                        }
 
 
                }
                }
 
 
        }
        }
        else {
        else {  printk(KERN_ALERT "DATA TRANS ERROR %d\n", host->registers.data_int_status);
                sg= &data->sg[0];
 
                writel(SD_DISABLE, host->base + SD_SOFTWARE_RST);
 
                writel(SD_ENABLE, host->base + SD_SOFTWARE_RST);
 
 
 
 
                                data->error = -ETIMEDOUT;
                        if ((host->registers.data_int_status & MRC) == MRC)
                        if ((host->registers.data_int_status & MRC) == MRC)
                                host->data->error = -ETIMEDOUT;
                                data->error = -ETIMEDOUT;
                        if ((host->registers.data_int_status &  CMDE) ==  CMDE)
                        if ((host->registers.data_int_status &  CMDE) ==  CMDE)
                                host->data->error = -EILSEQ;
                                data->error = -EILSEQ;
                        data->bytes_xfered =0;
                        data->bytes_xfered =0;
 
 
 
                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
                mmc_request_done(host->mmc, host->mrq);
                mmc_request_done(host->mmc, host->mrq);
 
 
 
 
Line 785... Line 730...
 
 
}
}
static int ocores_remove(struct platform_device *pdev)
static int ocores_remove(struct platform_device *pdev)
{
{
        struct mmc_host *mmc = platform_get_drvdata(pdev);
        struct mmc_host *mmc = platform_get_drvdata(pdev);
 
        struct ocores_host *host;
 
        struct resource *r;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
 
 
        platform_set_drvdata(pdev, NULL);
        platform_set_drvdata(pdev, NULL);
 
 
 
        tasklet_kill(&host->finish_cmd);
 
        tasklet_kill(&host->finish_data);
 
 
 
        free_irq(host->irq_cmd, host);
 
        free_irq(host->irq_dat, host);
 
 
 
        iounmap(host->base);
 
 
 
        release_mem_region(r->start, r->end - r->start + 1);
        if (mmc) {
        if (mmc) {
                struct ocores_host *host = mmc_priv(mmc);
                struct ocores_host *host = mmc_priv(mmc);
 
 
                mmc_remove_host(mmc);
                mmc_remove_host(mmc);
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.