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>
[subhashj@codeaurora.org: fixed merge conflicts]
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
Ritesh Harjani 2015-07-13 10:52:36 +05:30 committed by Subhash Jadavani
parent f052410b0b
commit e0ee5ff565
4 changed files with 59 additions and 1 deletions

View file

@ -921,12 +921,29 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
mmc_get_card(card);
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);
mmc_put_card(card);
goto cmd_done;
}
}
ioc_err = __mmc_blk_ioctl_cmd(card, md, idata);
mmc_put_card(card);
err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata);
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_done:
mmc_blk_put(md);
cmd_err:

View file

@ -366,7 +366,7 @@ static bool mmc_is_valid_state_for_clk_scaling(struct mmc_host *host)
return R1_CURRENT_STATE(status) == R1_STATE_TRAN;
}
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;
@ -389,6 +389,7 @@ static int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host)
out:
return err;
}
EXPORT_SYMBOL(mmc_cmdq_halt_on_empty_queue);
int mmc_clk_update_freq(struct mmc_host *host,
unsigned long freq, enum mmc_load state)

View file

@ -383,11 +383,26 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
int ret;
mmc_get_card(card);
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_put_card(card);
return ret;
@ -410,6 +425,17 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
return -ENOMEM;
mmc_get_card(card);
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);
mmc_put_card(card);
goto out_free_halt;
}
}
err = mmc_get_ext_csd(card, &ext_csd);
mmc_put_card(card);
if (err)
@ -421,10 +447,23 @@ 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:
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_free_halt:
kfree(buf);
return err;
}

View file

@ -135,6 +135,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,