示例#1
0
static void au1xmmc_send_pio(struct au1xmmc_host *host) 
{

	struct mmc_data *data = 0;
	int sg_len, max, count = 0;
	unsigned char *sg_ptr;
	u32 status = 0;
	struct scatterlist *sg;

	data = host->mrq->data;

	if (!(host->flags & HOST_F_XMIT)) 
		return;
	
	/* This is the pointer to the data buffer */
	sg = &data->sg[host->pio.index];
	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;

	/* This is the space left inside the buffer */
	sg_len = data->sg[host->pio.index].length - host->pio.offset;

	/* Check to if we need less then the size of the sg_buffer */

	max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
	if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER;

	for(count = 0; count < max; count++ ) {
		unsigned char val;

		status = au_readl(HOST_STATUS(host));		

		if (!(status & SD_STATUS_TH))
			break;

		val = *sg_ptr++;

		au_writel((unsigned long) val, HOST_TXPORT(host));
		au_sync();
	}

	host->pio.len -= count;
	host->pio.offset += count;

	if (count == sg_len) {
		host->pio.index++;
		host->pio.offset = 0;
	}

	if (host->pio.len == 0) {
		IRQ_OFF(host, SD_CONFIG_TH);

		if (host->flags & HOST_F_STOP)
			SEND_STOP(host);
		 
		tasklet_schedule(&host->data_task);
	}
}
static void pmpmci_data_complete(struct pmpmci_host *host, unsigned int status)
{
	struct mmc_request *mrq = host->mrq;
    struct sd_data_s *sd_data= host->platdata;		
	struct mmc_data *data;
	unsigned int crc;
	int timeout = 100000;
    #if 1
//printk("\n%s,%s():%d, enter host stutus=0x%x.", __FILE__, __FUNCTION__, __LINE__, host->status );
	/*WARN_ON((host->status != HOST_S_DATA) && (host->status != HOST_S_STOP));*/
	while ((host->status != HOST_S_DATA_SEND) && (host->status != HOST_S_STOP) && timeout > 0) {
		timeout--;
		//tasklet_schedule(&host->data_task);
	}
	if(timeout <= 0) {		
		printk("\nSD CMD not complete, dma interrupt run, wait timeout!!");		
		return;
	}
#endif
	if (host->mrq == NULL)
		return;

	data = mrq->cmd->data;
	
	data->error = 0;
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
        //sync_cache();
    /* Process any errors */
	crc = (status & SD_MMC_S_DATA_CRCERR);

	if (crc)
		data->error = -EILSEQ;

	/* Clear the CRC bits */
	sd_data->ops->clearStatus(&(sd_data->info),SD_MMC_S_DATA_CRCERR);

	data->bytes_xfered = 0;

        host->flags &= ~(HOST_F_XMIT | HOST_F_RECV);
	if (!data->error) {
		if (host->flags & HOST_F_DMA) {
			data->bytes_xfered = host->dma.totalxfer;
		} else
			data->bytes_xfered =
				(data->blocks * data->blksz) - host->pio.len;
	}
	sd_data->ops->stopTxCmd(&(sd_data->info));
	if (host->flags & HOST_F_STOP)
	{
		SEND_STOP(host);
    printk("\n%s(),%d.", __FUNCTION__, __LINE__);
		return;
	}
	pmpmci_finish_request(host);
    //printk("\n%s(),%d.", __FUNCTION__, __LINE__);
}
示例#3
0
static void au1xmmc_send_pio(struct au1xmmc_host *host)
{
	struct mmc_data *data;
	int sg_len, max, count;
	unsigned char *sg_ptr, val;
	u32 status;
	struct scatterlist *sg;

	data = host->mrq->data;

	if (!(host->flags & HOST_F_XMIT))
		return;

	
	sg = &data->sg[host->pio.index];
	sg_ptr = sg_virt(sg) + host->pio.offset;

	
	sg_len = data->sg[host->pio.index].length - host->pio.offset;

	
	max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
	if (max > AU1XMMC_MAX_TRANSFER)
		max = AU1XMMC_MAX_TRANSFER;

	for (count = 0; count < max; count++) {
		status = au_readl(HOST_STATUS(host));

		if (!(status & SD_STATUS_TH))
			break;

		val = *sg_ptr++;

		au_writel((unsigned long)val, HOST_TXPORT(host));
		au_sync();
	}

	host->pio.len -= count;
	host->pio.offset += count;

	if (count == sg_len) {
		host->pio.index++;
		host->pio.offset = 0;
	}

	if (host->pio.len == 0) {
		IRQ_OFF(host, SD_CONFIG_TH);

		if (host->flags & HOST_F_STOP)
			SEND_STOP(host);

		tasklet_schedule(&host->data_task);
	}
}
示例#4
0
文件: au1xmmc.c 项目: hajuuk/R7000
static void au1xmmc_receive_pio(struct au1xmmc_host *host)
{
	struct mmc_data *data;
	int max, count, sg_len = 0;
	unsigned char *sg_ptr = NULL;
	u32 status, val;
	struct scatterlist *sg;

	data = host->mrq->data;

	if (!(host->flags & HOST_F_RECV))
		return;

	max = host->pio.len;

	if (host->pio.index < host->dma.len) {
		sg = &data->sg[host->pio.index];
		sg_ptr = sg_virt(sg) + host->pio.offset;

		/* This is the space left inside the buffer */
		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;

		/* Check if we need less than the size of the sg_buffer */
		if (sg_len < max)
			max = sg_len;
	}

	if (max > AU1XMMC_MAX_TRANSFER)
		max = AU1XMMC_MAX_TRANSFER;

	for (count = 0; count < max; count++) {
		status = au_readl(HOST_STATUS(host));

		if (!(status & SD_STATUS_NE))
			break;

		if (status & SD_STATUS_RC) {
			DBG("RX CRC Error [%d + %d].\n", host->pdev->id,
					host->pio.len, count);
			break;
		}

		if (status & SD_STATUS_RO) {
			DBG("RX Overrun [%d + %d]\n", host->pdev->id,
					host->pio.len, count);
			break;
		}
		else if (status & SD_STATUS_RU) {
			DBG("RX Underrun [%d + %d]\n", host->pdev->id,
					host->pio.len,	count);
			break;
		}

		val = au_readl(HOST_RXPORT(host));

		if (sg_ptr)
			*sg_ptr++ = (unsigned char)(val & 0xFF);
	}

	host->pio.len -= count;
	host->pio.offset += count;

	if (sg_len && count == sg_len) {
		host->pio.index++;
		host->pio.offset = 0;
	}

	if (host->pio.len == 0) {
		/* IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF); */
		IRQ_OFF(host, SD_CONFIG_NE);

		if (host->flags & HOST_F_STOP)
			SEND_STOP(host);

		tasklet_schedule(&host->data_task);
	}
}