Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Add discard support to sd

SD spec v5.1 adds discard support. The flows and commands are similar to
mmc, so just set the discard arg in CMD38.

A host which supports DISCARD shall check if the DISCARD_SUPPORT (b313)
is set in the SD_STATUS register. If the card does not support discard,
the host shall not issue DISCARD command, but ERASE command instead.

Post the DISCARD operation, the card may de-allocate the discarded
blocks partially or completely. So the host mustn't make any assumptions
concerning the content of the discarded region. This is unlike ERASE
command, in which the region is guaranteed to contain either '0's or
'1's, depends on the content of DATA_STAT_AFTER_ERASE (b55) in the scr
register.

One more important difference compared to ERASE is the busy timeout
which we will address on the next patch.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Avri Altman and committed by
Ulf Hansson
bc47e2f6 85236d2b

+14 -5
+4 -4
drivers/mmc/core/core.c
··· 1847 1847 * @card: card to erase 1848 1848 * @from: first sector to erase 1849 1849 * @nr: number of sectors to erase 1850 - * @arg: erase command argument (SD supports only %SD_ERASE_ARG) 1850 + * @arg: erase command argument 1851 1851 * 1852 1852 * Caller must claim host before calling this function. 1853 1853 */ ··· 1864 1864 if (!card->erase_size) 1865 1865 return -EOPNOTSUPP; 1866 1866 1867 - if (mmc_card_sd(card) && arg != SD_ERASE_ARG) 1867 + if (mmc_card_sd(card) && arg != SD_ERASE_ARG && arg != SD_DISCARD_ARG) 1868 1868 return -EOPNOTSUPP; 1869 1869 1870 - if ((arg & MMC_SECURE_ARGS) && 1870 + if (mmc_card_mmc(card) && (arg & MMC_SECURE_ARGS) && 1871 1871 !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) 1872 1872 return -EOPNOTSUPP; 1873 1873 1874 - if ((arg & MMC_TRIM_ARGS) && 1874 + if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) && 1875 1875 !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) 1876 1876 return -EOPNOTSUPP; 1877 1877
+9 -1
drivers/mmc/core/sd.c
··· 231 231 { 232 232 unsigned int au, es, et, eo; 233 233 __be32 *raw_ssr; 234 + u32 resp[4] = {}; 235 + u8 discard_support; 234 236 int i; 235 237 236 238 if (!(card->csd.cmdclass & CCC_APP_SPEC)) { ··· 278 276 } 279 277 } 280 278 281 - card->erase_arg = SD_ERASE_ARG; 279 + /* 280 + * starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set 281 + */ 282 + resp[3] = card->raw_ssr[6]; 283 + discard_support = UNSTUFF_BITS(resp, 313 - 288, 1); 284 + card->erase_arg = (card->scr.sda_specx && discard_support) ? 285 + SD_DISCARD_ARG : SD_ERASE_ARG; 282 286 283 287 return 0; 284 288 }
+1
include/linux/mmc/sd.h
··· 95 95 * Erase/discard 96 96 */ 97 97 #define SD_ERASE_ARG 0x00000000 98 + #define SD_DISCARD_ARG 0x00000001 98 99 99 100 #endif /* LINUX_MMC_SD_H */