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: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
parent
d9ddd62943
commit
b3bf915308
5 changed files with 26 additions and 1 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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 {
|
||||||
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);
|
||||||
#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,
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue