| From 70b52f09080565030a530a784f1c9948a7f48ca3 Mon Sep 17 00:00:00 2001 |
| From: Bean Huo <beanhuo@micron.com> |
| Date: Tue, 4 May 2021 22:32:09 +0200 |
| Subject: mmc: block: Disable CMDQ on the ioctl path |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Bean Huo <beanhuo@micron.com> |
| |
| 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> |
| |
| --- |
| drivers/mmc/core/block.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/drivers/mmc/core/block.c |
| +++ b/drivers/mmc/core/block.c |
| @@ -1003,6 +1003,12 @@ static void mmc_blk_issue_drv_op(struct |
| |
| 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++) { |
| @@ -1013,6 +1019,8 @@ static void mmc_blk_issue_drv_op(struct |
| /* 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, |