mmc: dw_mmc: Fix occasional hang after tuning on eMMC [Linux 4.14.137]

This Linux kernel change "mmc: dw_mmc: Fix occasional hang after tuning on eMMC" is included in the Linux 4.14.137 release. This change is authored by Douglas Anderson <dianders [at] chromium.org> on Mon Jul 8 12:56:13 2019 -0700. The commit for this change in Linux stable tree is bdbe5dc (patch) which is from upstream commit ba2d139. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream ba2d139.

mmc: dw_mmc: Fix occasional hang after tuning on eMMC

commit ba2d139b02ba684c6c101de42fed782d6cd2b997 upstream.

In commit 46d179525a1f ("mmc: dw_mmc: Wait for data transfer after
response errors.") we fixed a tuning-induced hang that I saw when
stress testing tuning on certain SD cards.  I won't re-hash that whole
commit, but the summary is that as a normal part of tuning you need to
deal with transfer errors and there were cases where these transfer
errors was putting my system into a bad state causing all future
transfers to fail.  That commit fixed handling of the transfer errors
for me.

In downstream Chrome OS my fix landed and had the same behavior for
all SD/MMC commands.  However, it looks like when the commit landed
upstream we limited it to only SD tuning commands.  Presumably this
was to try to get around problems that Alim Akhtar reported on exynos
[1].

Unfortunately while stress testing reboots (and suspend/resume) on
some rk3288-based Chromebooks I found the same problem on the eMMC on
some of my Chromebooks (the ones with Hynix eMMC).  Since the eMMC
tuning command is different (MMC_SEND_TUNING_BLOCK_HS200
vs. MMC_SEND_TUNING_BLOCK) we were basically getting back into the
same situation.

I'm hoping that whatever problems exynos was having in the past are
somehow magically fixed now and we can make the behavior the same for
all commands.

[1] https://lkml.kernel.org/r/CAGOxZ53WfNbaMe0_AM0qBqU47kAfgmPBVZC8K8Y-_J3mDMqW4A@mail.gmail.com

Fixes: 46d179525a1f ("mmc: dw_mmc: Wait for data transfer after response errors.")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Alim Akhtar <alim.akhtar@gmail.com>
Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/mmc/host/dw_mmc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 5252885..32001d4 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2046,8 +2046,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
                 * delayed. Allowing the transfer to take place
                 * avoids races and keeps things simple.
                 */
-               if ((err != -ETIMEDOUT) &&
-                   (cmd->opcode == MMC_SEND_TUNING_BLOCK)) {
+               if (err != -ETIMEDOUT) {
                    state = STATE_SENDING_DATA;
                    continue;
                }

Leave a Reply

Your email address will not be published. Required fields are marked *