/* * 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; controller->MCI_IDR = 0xffffffff; cmd->resp[0] = controller->MCI_RSPR[0]; cmd->resp[1] = controller->MCI_RSPR[1]; cmd->resp[2] = controller->MCI_RSPR[2]; cmd->resp[3] = controller->MCI_RSPR[3]; if (host->buffer) { dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address); host->buffer = NULL; } status = controller->MCI_SR; DBG("Status = %08X [%08X %08X %08X %08X]\n", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); if (status & (AT91C_MCI_RINDE | AT91C_MCI_RDIRE | AT91C_MCI_RCRCE | AT91C_MCI_RENDE | AT91C_MCI_RTOE | AT91C_MCI_DCRCE | AT91C_MCI_DTOE | AT91C_MCI_OVRE | AT91C_MCI_UNRE)) { if ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND)) { cmd->error = MMC_ERR_NONE; } else { if (status & (AT91C_MCI_RTOE | AT91C_MCI_DTOE)) { cmd->error = MMC_ERR_TIMEOUT; } else if (status & (AT91C_MCI_RCRCE | AT91C_MCI_DCRCE)) { cmd->error = MMC_ERR_BADCRC; } else if (status & (AT91C_MCI_OVRE | AT91C_MCI_UNRE)) { cmd->error = MMC_ERR_FIFO; } else { cmd->error = MMC_ERR_FAILED; } DBG("Error detected and set to %d (cmd = %d, retries = %d)\n", cmd->error, cmd->opcode, cmd->retries); } } else { cmd->error = MMC_ERR_NONE; } if ((cmd->opcode == SD_APP_SET_BUS_WIDTH) && (cmd->error == MMC_ERR_NONE)) { if (cmd->arg == 2) controller->MCI_SDCR |= 0x80; else controller->MCI_SDCR &= ~0x80; } at91mci_process_next(host); }
/* * Handle an MMC request */ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct at91mci_host *host = mmc_priv(mmc); host->request = mrq; host->flags = 0; at91mci_process_next(host); }
/* * 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); }