diff options
author | Kyungmin Park <kyungmin.park@samsung.com> | 2011-10-17 20:34:04 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2011-10-26 16:32:27 -0400 |
commit | b3bf915308ca2b50f3beec6cc824083870f0f4b5 (patch) | |
tree | 955978242b333e1388358b4b50b5f8f4a5abca04 | |
parent | d9ddd62943ee07a75d0428ffcf52f1a747a28c39 (diff) |
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>
-rw-r--r-- | drivers/mmc/card/block.c | 4 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 14 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 4 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 3 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 2 |
5 files changed, 26 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e85816e1634a..370472797fff 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -756,7 +756,9 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) | |||
756 | from = blk_rq_pos(req); | 756 | from = blk_rq_pos(req); |
757 | nr = blk_rq_sectors(req); | 757 | nr = blk_rq_sectors(req); |
758 | 758 | ||
759 | if (mmc_can_trim(card)) | 759 | if (mmc_can_discard(card)) |
760 | arg = MMC_DISCARD_ARG; | ||
761 | else if (mmc_can_trim(card)) | ||
760 | arg = MMC_TRIM_ARG; | 762 | arg = MMC_TRIM_ARG; |
761 | else | 763 | else |
762 | arg = MMC_ERASE_ARG; | 764 | arg = MMC_ERASE_ARG; |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index d9836e5a4e59..772de2cdfd1d 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1709,10 +1709,24 @@ int mmc_can_trim(struct mmc_card *card) | |||
1709 | { | 1709 | { |
1710 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) | 1710 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) |
1711 | return 1; | 1711 | return 1; |
1712 | if (mmc_can_discard(card)) | ||
1713 | return 1; | ||
1712 | return 0; | 1714 | return 0; |
1713 | } | 1715 | } |
1714 | EXPORT_SYMBOL(mmc_can_trim); | 1716 | EXPORT_SYMBOL(mmc_can_trim); |
1715 | 1717 | ||
1718 | int mmc_can_discard(struct mmc_card *card) | ||
1719 | { | ||
1720 | /* | ||
1721 | * As there's no way to detect the discard support bit at v4.5 | ||
1722 | * use the s/w feature support filed. | ||
1723 | */ | ||
1724 | if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE) | ||
1725 | return 1; | ||
1726 | return 0; | ||
1727 | } | ||
1728 | EXPORT_SYMBOL(mmc_can_discard); | ||
1729 | |||
1716 | int mmc_can_sanitize(struct mmc_card *card) | 1730 | int mmc_can_sanitize(struct mmc_card *card) |
1717 | { | 1731 | { |
1718 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) | 1732 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f8ea9387d75c..54088768776c 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -452,6 +452,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
452 | card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; | 452 | card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; |
453 | } | 453 | } |
454 | 454 | ||
455 | /* eMMC v4.5 or later */ | ||
456 | if (card->ext_csd.rev >= 6) | ||
457 | card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; | ||
458 | |||
455 | card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; | 459 | card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; |
456 | if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) | 460 | if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) |
457 | card->erased_byte = 0xFF; | 461 | card->erased_byte = 0xFF; |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 711c3f8bfabd..551378508784 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -80,6 +80,9 @@ struct mmc_ext_csd { | |||
80 | u8 raw_sec_feature_support;/* 231 */ | 80 | u8 raw_sec_feature_support;/* 231 */ |
81 | u8 raw_trim_mult; /* 232 */ | 81 | u8 raw_trim_mult; /* 232 */ |
82 | u8 raw_sectors[4]; /* 212 - 4 bytes */ | 82 | u8 raw_sectors[4]; /* 212 - 4 bytes */ |
83 | |||
84 | unsigned int feature_support; | ||
85 | #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ | ||
83 | }; | 86 | }; |
84 | 87 | ||
85 | struct sd_scr { | 88 | struct sd_scr { |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 9585835cbc42..e918120235bd 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -146,6 +146,7 @@ extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); | |||
146 | #define MMC_ERASE_ARG 0x00000000 | 146 | #define MMC_ERASE_ARG 0x00000000 |
147 | #define MMC_SECURE_ERASE_ARG 0x80000000 | 147 | #define MMC_SECURE_ERASE_ARG 0x80000000 |
148 | #define MMC_TRIM_ARG 0x00000001 | 148 | #define MMC_TRIM_ARG 0x00000001 |
149 | #define MMC_DISCARD_ARG 0x00000003 | ||
149 | #define MMC_SECURE_TRIM1_ARG 0x80000001 | 150 | #define MMC_SECURE_TRIM1_ARG 0x80000001 |
150 | #define MMC_SECURE_TRIM2_ARG 0x80008000 | 151 | #define MMC_SECURE_TRIM2_ARG 0x80008000 |
151 | 152 | ||
@@ -156,6 +157,7 @@ extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | |||
156 | unsigned int arg); | 157 | unsigned int arg); |
157 | extern int mmc_can_erase(struct mmc_card *card); | 158 | extern int mmc_can_erase(struct mmc_card *card); |
158 | extern int mmc_can_trim(struct mmc_card *card); | 159 | extern int mmc_can_trim(struct mmc_card *card); |
160 | extern int mmc_can_discard(struct mmc_card *card); | ||
159 | extern int mmc_can_sanitize(struct mmc_card *card); | 161 | extern int mmc_can_sanitize(struct mmc_card *card); |
160 | extern int mmc_can_secure_erase_trim(struct mmc_card *card); | 162 | extern int mmc_can_secure_erase_trim(struct mmc_card *card); |
161 | extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, | 163 | extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, |