Commit 08ebf903 authored by Michael Wu's avatar Michael Wu Committed by Ulf Hansson

mmc: core: Fixup support for writeback-cache for eMMC and SD

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: 881d1c25 ("mmc: core: Add cache control for eMMC4.5 device")
Fixes: 130206a6 ("mmc: core: Add support for cache ctrl for SD cards")
Depends-on: 97fce126 ("mmc: block: Issue a cache flush only when it's enabled")
Reviewed-by: default avatarAvri Altman <Avri.Altman@wdc.com>
Signed-off-by: default avatarMichael 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: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 5d435933
...@@ -2382,6 +2382,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, ...@@ -2382,6 +2382,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
struct mmc_blk_data *md; struct mmc_blk_data *md;
int devidx, ret; int devidx, ret;
char cap_str[10]; char cap_str[10];
bool cache_enabled = false;
bool fua_enabled = false;
devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL); devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
if (devidx < 0) { if (devidx < 0) {
...@@ -2461,13 +2463,17 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, ...@@ -2461,13 +2463,17 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
md->flags |= MMC_BLK_CMD23; md->flags |= MMC_BLK_CMD23;
} }
if (mmc_card_mmc(card) && if (md->flags & MMC_BLK_CMD23 &&
md->flags & MMC_BLK_CMD23 &&
((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
card->ext_csd.rel_sectors)) { card->ext_csd.rel_sectors)) {
md->flags |= MMC_BLK_REL_WR; 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, string_get_size((u64)size, 512, STRING_UNITS_2,
cap_str, sizeof(cap_str)); cap_str, sizeof(cap_str));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment