提交 b3bf9153 编写于 作者: K Kyungmin Park 提交者: Chris Ball

mmc: core: new discard feature support at eMMC v4.5

MMC v4.5 supports the DISCARD feature (CMD38).  It's different from
trim and there's no check bit.  Currently it's only supported at v4.5.
Signed-off-by: NKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: NJaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: NChris Ball <cjb@laptop.org>
上级 d9ddd629
...@@ -756,7 +756,9 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) ...@@ -756,7 +756,9 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
from = blk_rq_pos(req); from = blk_rq_pos(req);
nr = blk_rq_sectors(req); nr = blk_rq_sectors(req);
if (mmc_can_trim(card)) if (mmc_can_discard(card))
arg = MMC_DISCARD_ARG;
else if (mmc_can_trim(card))
arg = MMC_TRIM_ARG; arg = MMC_TRIM_ARG;
else else
arg = MMC_ERASE_ARG; arg = MMC_ERASE_ARG;
......
...@@ -1709,10 +1709,24 @@ int mmc_can_trim(struct mmc_card *card) ...@@ -1709,10 +1709,24 @@ int mmc_can_trim(struct mmc_card *card)
{ {
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
return 1; return 1;
if (mmc_can_discard(card))
return 1;
return 0; return 0;
} }
EXPORT_SYMBOL(mmc_can_trim); EXPORT_SYMBOL(mmc_can_trim);
int mmc_can_discard(struct mmc_card *card)
{
/*
* As there's no way to detect the discard support bit at v4.5
* use the s/w feature support filed.
*/
if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE)
return 1;
return 0;
}
EXPORT_SYMBOL(mmc_can_discard);
int mmc_can_sanitize(struct mmc_card *card) int mmc_can_sanitize(struct mmc_card *card)
{ {
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
......
...@@ -452,6 +452,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) ...@@ -452,6 +452,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
} }
/* eMMC v4.5 or later */
if (card->ext_csd.rev >= 6)
card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
card->erased_byte = 0xFF; card->erased_byte = 0xFF;
......
...@@ -80,6 +80,9 @@ struct mmc_ext_csd { ...@@ -80,6 +80,9 @@ struct mmc_ext_csd {
u8 raw_sec_feature_support;/* 231 */ u8 raw_sec_feature_support;/* 231 */
u8 raw_trim_mult; /* 232 */ u8 raw_trim_mult; /* 232 */
u8 raw_sectors[4]; /* 212 - 4 bytes */ u8 raw_sectors[4]; /* 212 - 4 bytes */
unsigned int feature_support;
#define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */
}; };
struct sd_scr { struct sd_scr {
......
...@@ -146,6 +146,7 @@ extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); ...@@ -146,6 +146,7 @@ extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
#define MMC_ERASE_ARG 0x00000000 #define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000 #define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001 #define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001 #define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000 #define MMC_SECURE_TRIM2_ARG 0x80008000
...@@ -156,6 +157,7 @@ extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, ...@@ -156,6 +157,7 @@ extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
unsigned int arg); unsigned int arg);
extern int mmc_can_erase(struct mmc_card *card); extern int mmc_can_erase(struct mmc_card *card);
extern int mmc_can_trim(struct mmc_card *card); extern int mmc_can_trim(struct mmc_card *card);
extern int mmc_can_discard(struct mmc_card *card);
extern int mmc_can_sanitize(struct mmc_card *card); extern int mmc_can_sanitize(struct mmc_card *card);
extern int mmc_can_secure_erase_trim(struct mmc_card *card); extern int mmc_can_secure_erase_trim(struct mmc_card *card);
extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册