Example #1
0
/*
 * Handle a command that has been completed
 */
static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status)
{
	struct mmc_command *cmd = host->cmd;
	struct mmc_data *data = cmd->data;

	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));

	cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
	cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
	cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
	cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));

	if (host->buffer) {
		dma_unmap_single(NULL,
				host->physical_address, host->total_length,
				DMA_TO_DEVICE);
		kfree(host->buffer);
		host->buffer = NULL;
	}

	pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
		 status, at91_mci_read(host, AT91_MCI_SR),
		 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	if (status & AT91_MCI_ERRORS) {
		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
			cmd->error = 0;
		}
		else {
			if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) {
				if (data) {
					if (status & AT91_MCI_DTOE)
						data->error = -ETIMEDOUT;
					else if (status & AT91_MCI_DCRCE)
						data->error = -EILSEQ;
				}
			} else {
				if (status & AT91_MCI_RTOE)
					cmd->error = -ETIMEDOUT;
				else if (status & AT91_MCI_RCRCE)
					cmd->error = -EILSEQ;
				else
					cmd->error = -EIO;
			}

			pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n",
				cmd->error, data ? data->error : 0,
				 cmd->opcode, cmd->retries);
		}
	}
	else
		cmd->error = 0;

	at91_mci_process_next(host);
}
Example #2
0
/*
 * Handle a command that has been completed
 */
static void at91mci_completed_command(struct at91mci_host *host)
{
	struct mmc_command *cmd = host->cmd;
	unsigned int status;

	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);

	cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
	cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
	cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
	cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));

	if (host->buffer) {
		dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address);
		host->buffer = NULL;
	}

	status = at91_mci_read(host, AT91_MCI_SR);

	pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
		 status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
			AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
		if ((status & AT91_MCI_RCRCE) &&
			((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
			cmd->error = MMC_ERR_NONE;
		}
		else {
			if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
				cmd->error = MMC_ERR_TIMEOUT;
			else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
				cmd->error = MMC_ERR_BADCRC;
			else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))
				cmd->error = MMC_ERR_FIFO;
			else
				cmd->error = MMC_ERR_FAILED;

			pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n",
				 cmd->error, cmd->opcode, cmd->retries);
		}
	}
	else
		cmd->error = MMC_ERR_NONE;

	at91mci_process_next(host);
}
Example #3
0
/*
 * Handle a command that has been completed
 */
static void at91_mci_completed_command(struct at91mci_host *host)
{
	struct mmc_command *cmd = host->cmd;
	unsigned int status;

	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);

	cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
	cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
	cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
	cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));

	if (host->buffer) {
		dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address);
		host->buffer = NULL;
	}

	status = at91_mci_read(host, AT91_MCI_SR);

	pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
		 status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	if (status & AT91_MCI_ERRORS) {
		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
			cmd->error = 0;
		}
		else {
			if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
				cmd->error = -ETIMEDOUT;
			else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
				cmd->error = -EILSEQ;
			else
				cmd->error = -EIO;

			pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n",
				 cmd->error, cmd->opcode, cmd->retries);
		}
	}
	else
		cmd->error = 0;

	at91_mci_process_next(host);
}