diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-12 13:57:33 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-12 13:57:33 -0800 |
commit | 20077583ccdd4db8aa626eae442e030d217901db (patch) | |
tree | 56b3a55134f9398ddc8865784e1b80ca5966f211 /drivers/mmc/core/block.c | |
parent | 0c4b09cb542fd0c4134e3f87442c89abffbfeedd (diff) | |
parent | 5d40213347480e3ab903d5438dbd0d6b0110e6b8 (diff) |
Merge tag 'mmc-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Don't force a retune before eMMC RPMB switch
- Add optional HS400 tuning in HS400es initialization
- Add a sysfs node to for write-protect-group-size
- Add re-tuning test to the mmc-test module
- Use mrq.sbc to support close-ended ioctl requests
MMC host:
- mmci: Add support for SDIO in-band irqs for the stm32 variant
- mmc_spi: Remove broken support custom DMA mapped buffers
- mtk-sd: Improve and extend the support for tunings
- renesas_sdhi: Document support for the RZ/Five variant
- sdhci_am654: Drop support for the ti,otap-del-sel DT property
- sdhci-brcmstb: Add support for the brcm 74165b0 variant
- sdhci-msm: Add compatibles for IPQ4019 and IPQ8074
- sdhci-of-dwcmshc: Add support for the T-Head TH1520 variant
- sdhci-xenon: Add support for the Marvell ac5 variant"
* tag 'mmc-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (27 commits)
mmc: xenon: Add ac5 support via bounce buffer
dt-bindings: mmc: add Marvell ac5
mmc: sdhci-brcmstb: add new sdhci reset sequence for brcm 74165b0
dt-bindings: mmc: brcm,sdhci-brcmstb: Add support for 74165b0
mmc: core: Do not force a retune before RPMB switch
mmc: core: Add HS400 tuning in HS400es initialization
mmc: sdhci_omap: Fix TI SoC dependencies
mmc: sdhci_am654: Fix TI SoC dependencies
mmc: core: Add wp_grp_size sysfs node
mmc: mmc_test: Add re-tuning test
mmc: mmc_spi: remove custom DMA mapped buffers
dt-bindings: mmc: sdhci-msm: document dedicated IPQ4019 and IPQ8074
dt-bindings: mmc: synopsys-dw-mshc: add iommus for Intel SocFPGA
mmc: mtk-sd: Extend number of tuning steps
dt-bindings: mmc: mtk-sd: add tuning steps related property
mmc: sdhci-omap: don't misuse kernel-doc marker
mmc: mtk-sd: Increase the verbosity of msdc_track_cmd_data
mmc: core: Use mrq.sbc in close-ended ffu
mmc: sdhci_am654: Drop lookup for deprecated ti,otap-del-sel
mmc: sdhci-of-dwcmshc: Use logical OR instead of bitwise OR in dwcmshc_probe()
...
Diffstat (limited to 'drivers/mmc/core/block.c')
-rw-r--r-- | drivers/mmc/core/block.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 134c36edb6cf..32d49100dff5 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -400,6 +400,10 @@ struct mmc_blk_ioc_data { struct mmc_ioc_cmd ic; unsigned char *buf; u64 buf_bytes; + unsigned int flags; +#define MMC_BLK_IOC_DROP BIT(0) /* drop this mrq */ +#define MMC_BLK_IOC_SBC BIT(1) /* use mrq.sbc */ + struct mmc_rpmb_data *rpmb; }; @@ -465,7 +469,7 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, } static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct mmc_blk_ioc_data *idata) + struct mmc_blk_ioc_data **idatas, int i) { struct mmc_command cmd = {}, sbc = {}; struct mmc_data data = {}; @@ -475,10 +479,18 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, unsigned int busy_timeout_ms; int err; unsigned int target_part; + struct mmc_blk_ioc_data *idata = idatas[i]; + struct mmc_blk_ioc_data *prev_idata = NULL; if (!card || !md || !idata) return -EINVAL; + if (idata->flags & MMC_BLK_IOC_DROP) + return 0; + + if (idata->flags & MMC_BLK_IOC_SBC) + prev_idata = idatas[i - 1]; + /* * The RPMB accesses comes in from the character device, so we * need to target these explicitly. Else we just target the @@ -532,7 +544,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, return err; } - if (idata->rpmb) { + if (idata->rpmb || prev_idata) { sbc.opcode = MMC_SET_BLOCK_COUNT; /* * We don't do any blockcount validation because the max size @@ -540,6 +552,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, * 'Reliable Write' bit here. */ sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31)); + if (prev_idata) + sbc.arg = prev_idata->ic.arg; sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; mrq.sbc = &sbc; } @@ -557,6 +571,15 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, mmc_wait_for_req(card->host, &mrq); memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); + if (prev_idata) { + memcpy(&prev_idata->ic.response, sbc.resp, sizeof(sbc.resp)); + if (sbc.error) { + dev_err(mmc_dev(card->host), "%s: sbc error %d\n", + __func__, sbc.error); + return sbc.error; + } + } + if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", __func__, cmd.error); @@ -1034,6 +1057,20 @@ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) md->reset_done &= ~type; } +static void mmc_blk_check_sbc(struct mmc_queue_req *mq_rq) +{ + struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data; + int i; + + for (i = 1; i < mq_rq->ioc_count; i++) { + if (idata[i - 1]->ic.opcode == MMC_SET_BLOCK_COUNT && + mmc_op_multi(idata[i]->ic.opcode)) { + idata[i - 1]->flags |= MMC_BLK_IOC_DROP; + idata[i]->flags |= MMC_BLK_IOC_SBC; + } + } +} + /* * The non-block commands come back from the block layer after it queued it and * processed it with all other requests and then they get issued in this @@ -1061,11 +1098,14 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) if (ret) break; } + + mmc_blk_check_sbc(mq_rq); + fallthrough; case MMC_DRV_OP_IOCTL_RPMB: idata = mq_rq->drv_op_data; for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { - ret = __mmc_blk_ioctl_cmd(card, md, idata[i]); + ret = __mmc_blk_ioctl_cmd(card, md, idata, i); if (ret) break; } |