The busy timeout for the CMD5 to put the eMMC into sleep state, is specific to the card. Potentially the timeout may exceed the host->max_busy_timeout. If that becomes the case, mmc_sleep() converts from using an R1B response to an R1 response, as to prevent the host from doing HW busy detection.
However, it has turned out that some hosts requires an R1B response no matter what, so let's respect that via checking MMC_CAP_NEED_RSP_BUSY. Note that, if the R1B gets enforced, the host becomes fully responsible of managing the needed busy timeout, in one way or the other.
Suggested-by: Sowjanya Komatineni skomatineni@nvidia.com Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org --- drivers/mmc/core/mmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f6912ded652d..de14b5845f52 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host) * If the max_busy_timeout of the host is specified, validate it against * the sleep cmd timeout. A failure means we need to prevent the host * from doing hw busy detection, which is done by converting to a R1 - * response instead of a R1B. + * response instead of a R1B. Note, some hosts requires R1B, which also + * means they are on their own when it comes to deal with the busy + * timeout. */ - if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && + (timeout_ms > host->max_busy_timeout)) { cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; } else { cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
Hi Ulf,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master] [also build test ERROR on v5.6-rc5 next-20200311] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Ulf-Hansson/mmc-core-Respect-MMC_CA... base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e3a36eb6dfaeea8175c05d5915dcf0b939be6dab config: mips-vocore2_defconfig (attached as .config) compiler: mipsel-linux-gcc (GCC) 5.5.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=5.5.0 make.cross ARCH=mips
If you fix the issue, kindly add following tag Reported-by: kbuild test robot lkp@intel.com
All errors (new ones prefixed by >>):
drivers/mmc/core/mmc.c: In function 'mmc_sleep':
drivers/mmc/core/mmc.c:1917:21: error: 'MMC_CAP_NEED_RSP_BUSY' undeclared (first use in this function)
if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && ^ drivers/mmc/core/mmc.c:1917:21: note: each undeclared identifier is reported only once for each function it appears in
vim +/MMC_CAP_NEED_RSP_BUSY +1917 drivers/mmc/core/mmc.c
1890 1891 static int mmc_sleep(struct mmc_host *host) 1892 { 1893 struct mmc_command cmd = {}; 1894 struct mmc_card *card = host->card; 1895 unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); 1896 int err; 1897 1898 /* Re-tuning can't be done once the card is deselected */ 1899 mmc_retune_hold(host); 1900 1901 err = mmc_deselect_cards(host); 1902 if (err) 1903 goto out_release; 1904 1905 cmd.opcode = MMC_SLEEP_AWAKE; 1906 cmd.arg = card->rca << 16; 1907 cmd.arg |= 1 << 15; 1908 1909 /* 1910 * If the max_busy_timeout of the host is specified, validate it against 1911 * the sleep cmd timeout. A failure means we need to prevent the host 1912 * from doing hw busy detection, which is done by converting to a R1 1913 * response instead of a R1B. Note, some hosts requires R1B, which also 1914 * means they are on their own when it comes to deal with the busy 1915 * timeout. 1916 */
1917 if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
1918 (timeout_ms > host->max_busy_timeout)) { 1919 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1920 } else { 1921 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1922 cmd.busy_timeout = timeout_ms; 1923 } 1924 1925 err = mmc_wait_for_cmd(host, &cmd, 0); 1926 if (err) 1927 goto out_release; 1928 1929 /* 1930 * If the host does not wait while the card signals busy, then we will 1931 * will have to wait the sleep/awake timeout. Note, we cannot use the 1932 * SEND_STATUS command to poll the status because that command (and most 1933 * others) is invalid while the card sleeps. 1934 */ 1935 if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 1936 mmc_delay(timeout_ms); 1937 1938 out_release: 1939 mmc_retune_release(host); 1940 return err; 1941 } 1942
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Ulf,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master] [also build test ERROR on v5.6-rc5 next-20200311] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Ulf-Hansson/mmc-core-Respect-MMC_CA... base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e3a36eb6dfaeea8175c05d5915dcf0b939be6dab config: sparc64-allyesconfig (attached as .config) compiler: sparc64-linux-gcc (GCC) 9.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=9.2.0 make.cross ARCH=sparc64
If you fix the issue, kindly add following tag Reported-by: kbuild test robot lkp@intel.com
All errors (new ones prefixed by >>):
drivers/mmc/core/mmc.c: In function 'mmc_sleep':
drivers/mmc/core/mmc.c:1917:21: error: 'MMC_CAP_NEED_RSP_BUSY' undeclared (first use in this function); did you mean 'MMC_CAP_NEEDS_POLL'?
1917 | if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && | ^~~~~~~~~~~~~~~~~~~~~ | MMC_CAP_NEEDS_POLL drivers/mmc/core/mmc.c:1917:21: note: each undeclared identifier is reported only once for each function it appears in
vim +1917 drivers/mmc/core/mmc.c
1890 1891 static int mmc_sleep(struct mmc_host *host) 1892 { 1893 struct mmc_command cmd = {}; 1894 struct mmc_card *card = host->card; 1895 unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); 1896 int err; 1897 1898 /* Re-tuning can't be done once the card is deselected */ 1899 mmc_retune_hold(host); 1900 1901 err = mmc_deselect_cards(host); 1902 if (err) 1903 goto out_release; 1904 1905 cmd.opcode = MMC_SLEEP_AWAKE; 1906 cmd.arg = card->rca << 16; 1907 cmd.arg |= 1 << 15; 1908 1909 /* 1910 * If the max_busy_timeout of the host is specified, validate it against 1911 * the sleep cmd timeout. A failure means we need to prevent the host 1912 * from doing hw busy detection, which is done by converting to a R1 1913 * response instead of a R1B. Note, some hosts requires R1B, which also 1914 * means they are on their own when it comes to deal with the busy 1915 * timeout. 1916 */
1917 if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
1918 (timeout_ms > host->max_busy_timeout)) { 1919 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1920 } else { 1921 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1922 cmd.busy_timeout = timeout_ms; 1923 } 1924 1925 err = mmc_wait_for_cmd(host, &cmd, 0); 1926 if (err) 1927 goto out_release; 1928 1929 /* 1930 * If the host does not wait while the card signals busy, then we will 1931 * will have to wait the sleep/awake timeout. Note, we cannot use the 1932 * SEND_STATUS command to poll the status because that command (and most 1933 * others) is invalid while the card sleeps. 1934 */ 1935 if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 1936 mmc_delay(timeout_ms); 1937 1938 out_release: 1939 mmc_retune_release(host); 1940 return err; 1941 } 1942
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
linux-stable-mirror@lists.linaro.org