| From 08ebf903af57cda6d773f3dd1671b64f73b432b8 Mon Sep 17 00:00:00 2001 |
| From: Michael Wu <michael@allwinnertech.com> |
| Date: Thu, 31 Mar 2022 15:32:23 +0800 |
| Subject: mmc: core: Fixup support for writeback-cache for eMMC and SD |
| |
| From: Michael Wu <michael@allwinnertech.com> |
| |
| commit 08ebf903af57cda6d773f3dd1671b64f73b432b8 upstream. |
| |
| During the card initialization process, the mmc core checks whether the |
| eMMC/SD card supports an internal writeback-cache and then enables it |
| inside the card. |
| |
| Unfortunately, this isn't according to what the mmc core reports to the |
| upper block layer. Instead, the writeback-cache support with REQ_FLUSH and |
| REQ_FUA, are being enabled depending on whether the host supports the CMD23 |
| (MMC_CAP_CMD23) and whether an eMMC supports the reliable-write command. |
| |
| This is wrong and it may also sound awkward. In fact, it's a remnant |
| from when both eMMC/SD cards didn't have dedicated commands/support to |
| control the internal writeback-cache. In other words, it was the best we |
| could do at that point in time. |
| |
| To fix the problem, but also without breaking backwards compatibility, |
| let's align the REQ_FLUSH support with whether the writeback-cache became |
| successfully enabled - for both eMMC and SD cards. |
| |
| Cc: stable@kernel.org |
| Fixes: 881d1c25f765 ("mmc: core: Add cache control for eMMC4.5 device") |
| Fixes: 130206a615a9 ("mmc: core: Add support for cache ctrl for SD cards") |
| Depends-on: 97fce126e279 ("mmc: block: Issue a cache flush only when it's enabled") |
| Reviewed-by: Avri Altman <Avri.Altman@wdc.com> |
| Signed-off-by: Michael Wu <michael@allwinnertech.com> |
| Link: https://lore.kernel.org/r/20220331073223.106415-1-michael@allwinnertech.com |
| [Ulf: Re-wrote the commit message] |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/mmc/core/block.c | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/mmc/core/block.c |
| +++ b/drivers/mmc/core/block.c |
| @@ -2376,6 +2376,8 @@ static struct mmc_blk_data *mmc_blk_allo |
| struct mmc_blk_data *md; |
| int devidx, ret; |
| char cap_str[10]; |
| + bool cache_enabled = false; |
| + bool fua_enabled = false; |
| |
| devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL); |
| if (devidx < 0) { |
| @@ -2457,13 +2459,17 @@ static struct mmc_blk_data *mmc_blk_allo |
| md->flags |= MMC_BLK_CMD23; |
| } |
| |
| - if (mmc_card_mmc(card) && |
| - md->flags & MMC_BLK_CMD23 && |
| + if (md->flags & MMC_BLK_CMD23 && |
| ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || |
| card->ext_csd.rel_sectors)) { |
| md->flags |= MMC_BLK_REL_WR; |
| - blk_queue_write_cache(md->queue.queue, true, true); |
| + fua_enabled = true; |
| + cache_enabled = true; |
| } |
| + if (mmc_cache_enabled(card->host)) |
| + cache_enabled = true; |
| + |
| + blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled); |
| |
| string_get_size((u64)size, 512, STRING_UNITS_2, |
| cap_str, sizeof(cap_str)); |