>From d759e4606c498c63cbeae2ed00adf6c289acac6f Mon Sep 17 00:00:00 2001 From: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx> Date: Fri, 3 Dec 2010 19:34:15 +0800 Subject: [PATCH 4/4] mmc: Add HPI operation to interrupt BKOPS Before start a new user request, driver need to wait until the BKOPS finished, or use HPI to interrupt the BKOPS since user request has a higher priority than BKOPS. This patch can let driver use HPI command to interrupt BKOPS. Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx> --- drivers/mmc/core/core.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 51 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 4190424..4ac6c56 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -202,6 +202,51 @@ static void mmc_wait_done(struct mmc_request *mrq) } /** + * mmc_issue_hpi_cmd - start a hpi to interrupt background + * operations + * @card: MMC card need to interrupt + * + * start MMC_SEND_STATUS/MMC_STOP_TRANSMISSION to stop the + * background operations. + * + * return value: + * 0: successfully interrupt BKOPS + * -EINVAL: HPI command invalid + * -EIO: failed when interrupt BKOPS + */ +static int mmc_issue_hpi_cmd(struct mmc_card *card) +{ + struct mmc_command cmd; + unsigned int opcode; + unsigned int flags; + int err; + + opcode = card->ext_csd.hpi_cmd; + if (opcode == MMC_STOP_TRANSMISSION) + flags = MMC_RSP_R1B | MMC_CMD_AC; + else if (opcode == MMC_SEND_STATUS) + flags = MMC_RSP_R1 | MMC_CMD_AC; + else + return -EINVAL; + + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = opcode; + cmd.arg = card->rca << 16 | 1; + cmd.flags = flags; + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err || (cmd.resp[0] & R1_ERROR_RESPONSE)) { + printk(KERN_ERR "error %d requesting status %#x\n", + err, cmd.resp[0]); + /* + * abandon this BKOPS, let block layer handle + * this + */ + return -EIO; + } + return 0; +} + +/** * mmc_wait_for_bkops- start a bkops check and wait for * completion * @card: MMC card need to check @@ -224,9 +269,14 @@ retry: if (card->ext_csd.hpi_en) { /* - * TODO * HPI to interrupt BKOPS if supported */ + err = mmc_issue_hpi_cmd(card); + if (err == -EINVAL) { + /* disable HPI feature */ + card->ext_csd.hpi_en = 0; + goto retry; + } } else { memset(&cmd, 0, sizeof(struct mmc_command)); -- 1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html