static void ak98_mci_request_end(struct ak98_mci_host *host, struct mmc_request *mrq) { int not_retry = 0; PK1("%s\n", __func__); writel(0, host->base + AK98MCICOMMAND); BUG_ON(host->data); host->mrq = NULL; host->cmd = NULL; if(l2_mci_bufid != BUF_NULL) { ak98_l2_free(ADDR_MMC_SD); l2_mci_bufid = BUF_NULL; } if (mrq->data) mrq->data->bytes_xfered = host->data_xfered; /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... */ spin_unlock(&host->lock); not_retry = (!mrq->cmd->error) || ((mrq->cmd->error && (mrq->cmd->retries == 0))); mmc_request_done(host->mmc, mrq); #ifdef CONFIG_MTD_NAND_AK98 /*if request fail,then mmc_request_done send request again, * ak98_mci_send_request not down nand_lock in interrupt,so not to up nand_lock. */ if (not_retry) { up(&nand_lock); } #endif #ifdef CONFIG_CPU_FREQ /*if request fail,then mmc_request_done send request again, * ak98_mci_send_request not down freq_lock in interrupt,so not to unlock freq_lock. */ if (not_retry) { up(&host->freq_lock); } #endif spin_lock(&host->lock); }
static void hi_mci_finish_request(struct himci_host *host, struct mmc_request *mrq) { himci_trace(2, "begin"); himci_assert(host); himci_assert(mrq); host->mrq = NULL; host->cmd = NULL; host->data = NULL; mmc_request_done(host->mmc, mrq); }
static void mmc_finish_request(struct asic3_mmc_host *host) { struct mmc_request *mrq = host->mrq; /* Write something to end the command */ host->mrq = NULL; host->cmd = NULL; host->data = NULL; mmc_request_done(host->mmc, mrq); }
static int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq) { struct meson_host *host = mmc_priv(mmc); WARN_ON(host->mrq != mrq); host->mrq = NULL; host->cmd = NULL; mmc_request_done(host->mmc, mrq); return 0; }
static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { writel(0, host->base + MMCICOMMAND); BUG_ON(host->data); host->mrq = NULL; host->cmd = NULL; mmc_request_done(host->mmc, mrq); }
static void nuc970_emmc_send_stop(struct nuc970_emmc_host *host, struct mmc_command *cmd) { unsigned int csr; unsigned int block_length; unsigned int blocks; host->cmd = cmd; emmc_host = host; emmc_state = 0; emmc_state_xfer = 0; if (nuc970_emmc_read(REG_NAND_FMICSR) != FMICSR_EMMCEN) nuc970_emmc_write(REG_NAND_FMICSR, FMICSR_EMMCEN); csr = nuc970_emmc_read(REG_EMMCCSR) & 0xff00c080; csr = csr | (cmd->opcode << 8) | EMMCCSR_CO_EN; // set command code and enable command out emmc_event |= EMMC_EVENT_CMD_OUT; if (host->bus_mode == MMC_BUS_WIDTH_4) csr |= EMMCCSR_DBW; if (mmc_resp_type(cmd) != MMC_RSP_NONE) { /* if a response is expected then allow maximum response latancy */ /* set 136 bit response for R2, 48 bit response otherwise */ if (mmc_resp_type(cmd) == MMC_RSP_R2) { csr |= EMMCCSR_R2_EN; emmc_event |= EMMC_EVENT_RSP2_IN; } else { csr |= EMMCCSR_RI_EN; emmc_event |= EMMC_EVENT_RSP_IN; } nuc970_emmc_write(REG_EMMCISR, EMMCISR_RITO_IF); emmc_ri_timeout = 0; nuc970_emmc_write(REG_EMMCTMOUT, 0xffff); } nuc970_emmc_write(REG_EMMCIER, nuc970_emmc_read(REG_EMMCIER) & ~EMMCIER_BLKD_IE); //disable SD interrupt block_length = 0; blocks = 0; nuc970_emmc_write(REG_EMMCARG, cmd->arg); nuc970_emmc_write(REG_EMMCCSR, csr); emmc_send_cmd = 1; wake_up_interruptible(&emmc_event_wq); mmc_request_done(host->mmc, host->request); }
/* * Process the next step in the request */ static void at91_mci_process_next(struct at91mci_host *host) { if (!(host->flags & FL_SENT_COMMAND)) { host->flags |= FL_SENT_COMMAND; at91_mci_send_command(host, host->request->cmd); } else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; at91_mci_send_command(host, host->request->stop); } else mmc_request_done(host->mmc, host->request); }
static void jz4740_mmc_request_done(struct jz4740_mmc_host *host) { struct mmc_request *req; struct mmc_data *data; req = host->req; data = req->data; host->req = NULL; if (data && data->host_cookie == COOKIE_MAPPED) jz4740_mmc_dma_unmap(host, data); mmc_request_done(host->mmc, req); }
static void mmcif_timeout_work(struct work_struct *work) { struct delayed_work *d = container_of(work, struct delayed_work, work); struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work); struct mmc_request *mrq = host->mrq; unsigned long flags; if (host->dying) /* Don't run after mmc_remove_host() */ return; dev_err(&host->pd->dev, "Timeout waiting for %u on CMD%u\n", host->wait_for, mrq->cmd->opcode); spin_lock_irqsave(&host->lock, flags); if (host->state == STATE_IDLE) { spin_unlock_irqrestore(&host->lock, flags); return; } host->state = STATE_TIMEOUT; spin_unlock_irqrestore(&host->lock, flags); /* * Handle races with cancel_delayed_work(), unless * cancel_delayed_work_sync() is used */ switch (host->wait_for) { case MMCIF_WAIT_FOR_CMD: mrq->cmd->error = sh_mmcif_error_manage(host); break; case MMCIF_WAIT_FOR_STOP: mrq->stop->error = sh_mmcif_error_manage(host); break; case MMCIF_WAIT_FOR_MREAD: case MMCIF_WAIT_FOR_MWRITE: case MMCIF_WAIT_FOR_READ: case MMCIF_WAIT_FOR_WRITE: case MMCIF_WAIT_FOR_READ_END: case MMCIF_WAIT_FOR_WRITE_END: mrq->data->error = sh_mmcif_error_manage(host); break; default: BUG(); } host->state = STATE_IDLE; host->wait_for = MMCIF_WAIT_FOR_REQUEST; host->mrq = NULL; mmc_request_done(host->mmc, mrq); }
static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sh_mmcif_host *host = mmc_priv(mmc); unsigned long flags; spin_lock_irqsave(&host->lock, flags); if (host->state != STATE_IDLE) { dev_dbg(&host->pd->dev, "%s() rejected, state %u\n", __func__, host->state); spin_unlock_irqrestore(&host->lock, flags); mrq->cmd->error = -EAGAIN; mmc_request_done(mmc, mrq); return; } host->state = STATE_REQUEST; spin_unlock_irqrestore(&host->lock, flags); switch (mrq->cmd->opcode) { /* MMCIF does not support SD/SDIO command */ case MMC_SLEEP_AWAKE: /* = SD_IO_SEND_OP_COND (5) */ case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ if ((mrq->cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR) break; case MMC_APP_CMD: case SD_IO_RW_DIRECT: host->state = STATE_IDLE; mrq->cmd->error = -ETIMEDOUT; mmc_request_done(mmc, mrq); return; default: break; } host->mrq = mrq; sh_mmcif_start_cmd(host, mrq); }
static void msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct msmsdcc_host *host = mmc_priv(mmc); unsigned long flags; WARN_ON(host->curr.mrq != NULL); WARN_ON(host->pwr == 0); #if defined (CONFIG_MACH_ACER_A1) if (mrq->cmd->opcode == 25) g_IS_SD_CMD25 = 1; #endif spin_lock_irqsave(&host->lock, flags); if (host->eject) { if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) { mrq->cmd->error = 0; mrq->data->bytes_xfered = mrq->data->blksz * mrq->data->blocks; } else mrq->cmd->error = -ENOMEDIUM; spin_unlock_irqrestore(&host->lock, flags); mmc_request_done(mmc, mrq); return; } host->curr.mrq = mrq; if (host->plat->dummy52_required) { if (host->dummy_52_needed) { if (mrq->data) { host->dummy_52_state = DUMMY_52_STATE_SENT; msmsdcc_start_command(host, &dummy52cmd, MCI_CPSM_PROGENA); spin_unlock_irqrestore(&host->lock, flags); return; } host->dummy_52_needed = 0; } if ((mrq->cmd->opcode == SD_IO_RW_EXTENDED) && (mrq->data)) host->dummy_52_needed = 1; } msmsdcc_request_start(host, mrq); spin_unlock_irqrestore(&host->lock, flags); }
/* * Notify the transfer complete to MMC core */ static void omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) { if (!data) { struct mmc_request *mrq = host->mrq; /* TC before CC from CMD6 - don't know why, but it happens */ if (host->cmd && host->cmd->opcode == 6 && host->response_busy) { host->response_busy = 0; return; } host->mrq = NULL; mmc_request_done(host->mmc, mrq); return; } host->data = NULL; if (host->use_dma && host->dma_ch != -1) dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, omap_hsmmc_get_dma_dir(host, data)); if (!data->error) data->bytes_xfered += data->blocks * (data->blksz); else data->bytes_xfered = 0; if (!data->stop) { host->mrq = NULL; mmc_request_done(host->mmc, data->mrq); return; } omap_hsmmc_start_command(host, data->stop, NULL); }
static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct s3cmci_host *host = mmc_priv(mmc); host->status = "mmc request"; host->cmd_is_stop = 0; host->mrq = mrq; if (s3cmci_card_present(host) == 0) { dbg(host, dbg_err, "%s: no medium present\n", __func__); host->mrq->cmd->error = -ENOMEDIUM; mmc_request_done(mmc, mrq); } else s3cmci_send_request(mmc); }
static void msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct msmsdcc_host *host = mmc_priv(mmc); unsigned long flags; WARN_ON(host->curr.mrq != NULL); WARN_ON(host->pwr == 0); spin_lock_irqsave(&host->lock, flags); host->stats.reqs++; if (host->eject) { if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) { mrq->cmd->error = 0; mrq->data->bytes_xfered = mrq->data->blksz * mrq->data->blocks; } else mrq->cmd->error = -ENOMEDIUM; spin_unlock_irqrestore(&host->lock, flags); mmc_request_done(mmc, mrq); return; } host->curr.mrq = mrq; if (mrq->data && mrq->data->flags & MMC_DATA_READ) msmsdcc_start_data(host, mrq->data); msmsdcc_start_command(host, mrq->cmd, 0); if (host->cmdpoll && !msmsdcc_spin_on_status(host, MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, CMD_SPINMAX)) { uint32_t status = readl(host->base + MMCISTATUS); msmsdcc_do_cmdirq(host, status); writel(MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT, host->base + MMCICLEAR); host->stats.cmdpoll_hits++; } else { host->stats.cmdpoll_misses++; mod_timer(&host->command_timer, jiffies + HZ); } spin_unlock_irqrestore(&host->lock, flags); }
static void at91_mci_process_next(struct at91mci_host *host) { if (!(host->flags & FL_SENT_COMMAND)) { host->flags |= FL_SENT_COMMAND; at91_mci_send_command(host, host->request->cmd); } else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; at91_mci_send_command(host, host->request->stop); } else { del_timer(&host->timer); if (cpu_is_at91rm9200()) at91_reset_host(host); mmc_request_done(host->mmc, host->request); } }
static void bcm2835_sdhost_tasklet_finish(unsigned long param) { struct bcm2835_host *host; unsigned long flags; struct mmc_request *mrq; host = (struct bcm2835_host *)param; spin_lock_irqsave(&host->lock, flags); /* * If this tasklet gets rescheduled while running, it will * be run again afterwards but without any active request. */ if (!host->mrq) { spin_unlock_irqrestore(&host->lock, flags); return; } del_timer(&host->timer); mrq = host->mrq; /* Drop the overclock after any data corruption, or after any error overclocked */ if (host->overclock) { if ((mrq->cmd && mrq->cmd->error) || (mrq->data && mrq->data->error) || (mrq->stop && mrq->stop->error)) { host->overclock_50--; pr_warn("%s: reducing overclock due to errors\n", mmc_hostname(host->mmc)); bcm2835_sdhost_set_clock(host,50*MHZ); mrq->cmd->error = -EILSEQ; mrq->cmd->retries = 1; } } host->mrq = NULL; host->cmd = NULL; host->data = NULL; mmiowb(); spin_unlock_irqrestore(&host->lock, flags); mmc_request_done(host->mmc, mrq); }
/* * This function is called to complete the command request. * * @param priv Pointer to MMC/SD priv structure * @param req Pointer to MMC/SD command request structure */ static void mxcmci_finish_request(struct mxcmci_priv *priv, struct mmc_request *req) { priv->req = NULL; priv->cmd = NULL; priv->data = NULL; if (priv->host->card && (priv->host->card->state & MMC_STATE_PRESENT)) { if (!(priv->host->card->ext_caps & MMC_CARD_CAPS_FORCE_CLK_KEEP)) mxcmci_stop_clock(priv); } else { mxcmci_stop_clock(priv); } mmc_request_done(priv->host, req); }
/* * Process the next step in the request */ static void at91_mci_process_next(struct at91mci_host *host) { if (!(host->flags & FL_SENT_COMMAND)) { host->flags |= FL_SENT_COMMAND; at91_mci_send_command(host, host->request->cmd); } else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; at91_mci_send_command(host, host->request->stop); } else { del_timer(&host->timer); /* the mci controller hangs after some transfers, * and the workaround is to reset it after each transfer. */ at91_reset_host(host); mmc_request_done(host->mmc, host->request); } }
static void au1xmmc_finish_request(struct au1xmmc_host *host) { struct mmc_request *mrq = host->mrq; host->mrq = NULL; host->flags &= HOST_F_ACTIVE | HOST_F_DMA; host->dma.len = 0; host->dma.dir = 0; host->pio.index = 0; host->pio.offset = 0; host->pio.len = 0; host->status = HOST_S_IDLE; mmc_request_done(host->mmc, mrq); }
/* Handle MMC request */ static void stmp3xxx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct stmp3xxx_mmc_host *host = mmc_priv(mmc); dev_dbg(host->dev, "MMC request\n"); host->mrq = mrq; stmp3xxx_mmc_start_cmd(host, mrq->cmd); if (mrq->data && mrq->data->stop) { dev_dbg(host->dev, "Stop opcode is %u\n", mrq->data->stop->opcode); stmp3xxx_mmc_start_cmd(host, mrq->data->stop); } host->mrq = NULL; mmc_request_done(mmc, mrq); }
static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { writel(0, host->base + MMCICOMMAND); host->mrq = NULL; host->cmd = NULL; if (mrq->data) mrq->data->bytes_xfered = host->data_xfered; /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... */ spin_unlock(&host->lock); mmc_request_done(host->mmc, mrq); spin_lock(&host->lock); }
static void sunximmc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sunxi_mmc_host *smc_host = mmc_priv(mmc); smc_host->mrq = mrq; if (sunximmc_card_present(mmc) == 0 || smc_host->ferror || !smc_host->power_on) { SMC_DBG("no medium present, ferr %d, pwd %d\n", smc_host->ferror, smc_host->power_on); smc_host->mrq->cmd->error = -ENOMEDIUM; mmc_request_done(mmc, mrq); } else { sdxc_request(smc_host, mrq); } }
static void ak98_sdio_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct ak98_mci_host *host = mmc_priv(mmc); PK1("%s: CMD%i\n", __func__, mrq->cmd->opcode); host->mrq = mrq; if (ak98_sdio_get_cd(mmc) == 0) { printk("%s: no medium present\n", __func__); host->mrq->cmd->error = -ENOMEDIUM; mmc_request_done(mmc, mrq); } else { ak98_sdio_send_request(mmc); } }
static void mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) { host->cmd = NULL; del_timer(&host->cmd_abort_timer); if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { /* response type 2 */ cmd->resp[3] = OMAP_MMC_READ(host, RSP0) | (OMAP_MMC_READ(host, RSP1) << 16); cmd->resp[2] = OMAP_MMC_READ(host, RSP2) | (OMAP_MMC_READ(host, RSP3) << 16); cmd->resp[1] = OMAP_MMC_READ(host, RSP4) | (OMAP_MMC_READ(host, RSP5) << 16); cmd->resp[0] = OMAP_MMC_READ(host, RSP6) | (OMAP_MMC_READ(host, RSP7) << 16); } else { /* response types 1, 1b, 3, 4, 5, 6 */ cmd->resp[0] = OMAP_MMC_READ(host, RSP6) | (OMAP_MMC_READ(host, RSP7) << 16); } } if (host->data == NULL || cmd->error) { struct mmc_host *mmc; if (host->data != NULL) mmc_omap_abort_xfer(host, host->data); host->mrq = NULL; mmc = host->mmc; mmc_omap_release_slot(host->current_slot, 1); mmc_request_done(mmc, cmd->mrq); } }
static int msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) { int retval = 0; BUG_ON(host->curr.data); host->curr.mrq = NULL; host->curr.cmd = NULL; if (mrq->data) mrq->data->bytes_xfered = host->curr.data_xfered; if (mrq->cmd->error == -ETIMEDOUT) mdelay(5); #ifdef CONFIG_MMC_MSM_PROG_DONE_SCAN if ((mrq->cmd->opcode == SD_IO_RW_EXTENDED) && (mrq->cmd->arg & 0x80000000)) { /* If its a write and a cmd53 set the prog_scan flag. */ host->prog_scan = 1; /* Send STOP to let the SDCC know to stop. */ writel(MCI_CSPM_MCIABORT, host->base + MMCICOMMAND); retval = 1; } if (mrq->cmd->opcode == SD_IO_RW_DIRECT) { /* Ok the cmd52 following a cmd53 is received */ /* clear all the flags. */ host->prog_scan = 0; host->prog_enable = 0; } #endif /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... */ spin_unlock(&host->lock); mmc_request_done(host->mmc, mrq); spin_lock(&host->lock); return retval; }
static void ak880xmci_setup_data(struct ak880xmci_host *host, struct mmc_data *data) { unsigned int regval, timeout, length; struct mmc_command *cmd = host->cmd; if (data->blksz & 0x3) { dbg("Unsopported block size"); cmd->error = -EINVAL; mmc_request_done(host->mmc, host->request); return; } length = data->blksz * data->blocks; timeout = (data->timeout_ns / 1000000) * (host->clkrate / 1000); /* mci clocks */ #ifdef L2_USING if (length >= 64) { regval = 0x1<<0 | 0x1<<16 | (data->blksz>>2)<<17; /* regval = 0x1<<0 | (data->blksz>>2)<<17; */ mci_write(host, MMC_DMA_MODE, regval); dbg("dmareg(0x%x)", regval); } else
/* * Handle an MMC request */ static void rk28_sdmmc0_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct rk28mci_host *host = mmc_priv(mmc); #ifdef CONFIG_ANDROID_POWER android_lock_suspend(&sdmmc0_request_lock); #endif host->request = mrq; host->cmd_is_stop = 0; host->cmderror = 0; rk28_sdmmc_send_request(mmc); mmc_request_done(mmc, mrq); #ifdef CONFIG_ANDROID_POWER android_unlock_suspend(&sdmmc0_request_lock); #endif }
static void rk_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct rk_mmc *host = mmc_priv(mmc); struct mmc_command *cmd; WARN_ON(host->mrq); WARN_ON(host->state != STATE_IDLE); if(host->shutdown == 1){ cmd = mrq->sbc ? mrq->sbc : mrq->cmd; cmd->error = -EIO; mmc_request_done(host->mmc, mrq); return; } spin_lock_bh(&host->lock); host->state = STATE_SENDING_CMD; host->mrq = mrq; rk_mmc_start_request(host); spin_unlock_bh(&host->lock); }
static void jz4740_mmc_request_done(struct jz4740_mmc_host *host) { struct mmc_request *req; unsigned long flags; spin_lock_irqsave(&host->lock, flags); req = host->req; host->req = NULL; host->waiting = 0; spin_unlock_irqrestore(&host->lock, flags); if (!unlikely(req)) return; /* if (req->cmd->error != 0) { printk("error\n"); jz4740_mmc_reset(host); }*/ mmc_request_done(host->mmc, req); }
static void mxs_mmc_request_done(struct mxs_mmc_host *host) { struct mmc_command *cmd = host->cmd; struct mmc_data *data = host->data; struct mmc_request *mrq = host->mrq; struct mxs_ssp *ssp = &host->ssp; if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { if (mmc_resp_type(cmd) & MMC_RSP_136) { cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp)); cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp)); cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp)); } else { cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); } } if (data) { dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, ssp->dma_dir); /* * If there was an error on any block, we mark all * data blocks as being in error. */ if (!data->error) data->bytes_xfered = data->blocks * data->blksz; else data->bytes_xfered = 0; host->data = NULL; if (mrq->stop) { mxs_mmc_start_cmd(host, mrq->stop); return; } } host->mrq = NULL; mmc_request_done(host->mmc, mrq); }