Message ID | 20210504203209.361597-1-huobean@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v1] mmc: block: Disable CMDQ on the ioctl path | expand |
On 4/05/21 11:32 pm, Bean Huo wrote: > From: Bean Huo <beanhuo@micron.com> > > 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> > --- > drivers/mmc/core/block.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c > index 689eb9afeeed..21fb99883b1e 100644 > --- a/drivers/mmc/core/block.c > +++ b/drivers/mmc/core/block.c > @@ -1004,6 +1004,11 @@ 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; > + } > case MMC_DRV_OP_IOCTL_RPMB: > idata = mq_rq->drv_op_data; > for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { > @@ -1014,6 +1019,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, >
On Tue, 4 May 2021 at 22:32, Bean Huo <huobean@gmail.com> wrote: > > From: Bean Huo <beanhuo@micron.com> > > 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> Applied for next and by adding a fixes/stable tag, thanks! Kind regards Uffe > --- > drivers/mmc/core/block.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c > index 689eb9afeeed..21fb99883b1e 100644 > --- a/drivers/mmc/core/block.c > +++ b/drivers/mmc/core/block.c > @@ -1004,6 +1004,11 @@ 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; > + } This should have a "fallthrough;" statement. No need for a respin, I have amended the change this time. > case MMC_DRV_OP_IOCTL_RPMB: > idata = mq_rq->drv_op_data; > for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { > @@ -1014,6 +1019,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, > -- > 2.25.1 > Kind regards Uffe
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 689eb9afeeed..21fb99883b1e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1004,6 +1004,11 @@ 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; + } case MMC_DRV_OP_IOCTL_RPMB: idata = mq_rq->drv_op_data; for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { @@ -1014,6 +1019,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,