mmc: core: Fix debugfs and IOCTL calls in cmdq mode

Currently getting status/ext_csd using debugfs or IOCTL
calls in cmdq mode is not working.
Fix it by halting the cmdq engine and making sure that
card queue is empty before issuing these cmds.

Change-Id: Idb89def9ff5c2fee6866759b9a8c652049552933
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
This commit is contained in:
Ritesh Harjani 2015-06-19 20:37:56 +05:30 committed by Gerrit - the friendly Code Review server
parent bafa8ed2c0
commit 0f9d90b9e0
4 changed files with 54 additions and 2 deletions

View File

@ -741,6 +741,16 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
mmc_rpm_hold(card->host, &card->dev);
mmc_claim_host(card->host);
if (mmc_card_cmdq(card)) {
err = mmc_cmdq_halt_on_empty_queue(card->host);
if (err) {
pr_err("%s: halt failed while doing %s err (%d)\n",
mmc_hostname(card->host),
__func__, err);
goto cmd_rel_host_halt;
}
}
err = mmc_blk_part_switch(card, md);
if (err)
goto cmd_rel_host;
@ -797,9 +807,14 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
}
cmd_rel_host:
if (mmc_card_cmdq(card)) {
if (mmc_cmdq_halt(card->host, false))
pr_err("%s: %s: cmdq unhalt failed\n",
mmc_hostname(card->host), __func__);
}
cmd_rel_host_halt:
mmc_release_host(card->host);
mmc_rpm_release(card->host, &card->dev);
cmd_done:
mmc_blk_put(md);
cmd_err:

View File

@ -3412,7 +3412,7 @@ out:
return err;
}
static int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
{
int err = 0;
@ -3433,6 +3433,7 @@ static int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
out:
return err;
}
EXPORT_SYMBOL(mmc_cmdq_halt_on_empty_queue);
/**
* mmc_clk_scaling() - clock scaling decision algorithm

View File

@ -311,10 +311,25 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
mmc_rpm_hold(card->host, &card->dev);
mmc_claim_host(card->host);
if (mmc_card_cmdq(card)) {
ret = mmc_cmdq_halt_on_empty_queue(card->host);
if (ret) {
pr_err("%s: halt failed while doing %s err (%d)\n",
mmc_hostname(card->host), __func__,
ret);
goto out;
}
}
ret = mmc_send_status(data, &status);
if (!ret)
*val = status;
if (mmc_card_cmdq(card)) {
if (mmc_cmdq_halt(card->host, false))
pr_err("%s: %s: cmdq unhalt failed\n",
mmc_hostname(card->host), __func__);
}
out:
mmc_release_host(card->host);
mmc_rpm_release(card->host, &card->dev);
@ -345,6 +360,17 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
mmc_rpm_hold(card->host, &card->dev);
mmc_claim_host(card->host);
if (mmc_card_cmdq(card)) {
err = mmc_cmdq_halt_on_empty_queue(card->host);
if (err) {
pr_err("%s: halt failed while doing %s err (%d)\n",
mmc_hostname(card->host), __func__,
err);
goto out_free_halt;
}
}
err = mmc_send_ext_csd(card, ext_csd);
mmc_release_host(card->host);
mmc_rpm_release(card->host, &card->dev);
@ -357,9 +383,18 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
BUG_ON(n != EXT_CSD_STR_LEN);
filp->private_data = buf;
if (mmc_card_cmdq(card)) {
if (mmc_cmdq_halt(card->host, false))
pr_err("%s: %s: cmdq unhalt failed\n",
mmc_hostname(card->host), __func__);
}
kfree(ext_csd);
return 0;
out_free_halt:
kfree(ext_csd);
out_free:
kfree(buf);
kfree(ext_csd);

View File

@ -117,6 +117,7 @@ struct mmc_cmdq_req;
extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks);
extern int mmc_cmdq_halt(struct mmc_host *host, bool enable);
extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host);
extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq,
int err);
extern int mmc_cmdq_start_req(struct mmc_host *host,