summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorBean Huo <beanhuo@micron.com>2021-05-04 22:32:09 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-14 16:53:48 +0200
commit5712b828b8d9856738ab8646ed127826c8c11a52 (patch)
tree4e4bb35b4ea10332bcd876d25f4b0e1cc9a18b8d /drivers/mmc
parent90d29149e32cc418343acfce6fada3a49de500e4 (diff)
downloadlinux-5712b828b8d9856738ab8646ed127826c8c11a52.tar.gz
linux-5712b828b8d9856738ab8646ed127826c8c11a52.tar.bz2
linux-5712b828b8d9856738ab8646ed127826c8c11a52.zip
mmc: block: Disable CMDQ on the ioctl path
commit 70b52f09080565030a530a784f1c9948a7f48ca3 upstream. According to the eMMC Spec: "When command queuing is enabled (CMDQ Mode En bit in CMDQ_MODE_EN field is set to ‘1’) class 11 commands are the only method through which data transfer tasks can be issued. Existing data transfer commands, namely CMD18/CMD17 and CMD25/CMD24, are not supported when command queuing is enabled." which means if CMDQ is enabled, the FFU commands will not be supported. To fix this issue, just simply disable CMDQ on the ioctl path, and re-enable CMDQ once ioctl request is completed. Tested-by: Michael Brunner <Michael.Brunner@kontron.com> Signed-off-by: Bean Huo <beanhuo@micron.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Fixes: 1e8e55b67030 (mmc: block: Add CQE support) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210504203209.361597-1-huobean@gmail.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/block.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 39f2864455a6..8322d22a59c4 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1053,6 +1053,12 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
switch (mq_rq->drv_op) {
case MMC_DRV_OP_IOCTL:
+ if (card->ext_csd.cmdq_en) {
+ ret = mmc_cmdq_disable(card);
+ if (ret)
+ break;
+ }
+ fallthrough;
case MMC_DRV_OP_IOCTL_RPMB:
idata = mq_rq->drv_op_data;
for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
@@ -1063,6 +1069,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
/* Always switch back to main area after RPMB access */
if (rpmb_ioctl)
mmc_blk_part_switch(card, 0);
+ else if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
+ mmc_cmdq_enable(card);
break;
case MMC_DRV_OP_BOOT_WP:
ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,