Skip to content

Commit 2830281

Browse files
ahunter6cjb
authored andcommitted
mmc: fixes for eMMC v4.5 sanitize operation
eMMC v4.5 sanitize operation erases all copies of unmapped data. However trim or erase operations must be used first to unmap the required sectors. That was not being done. Fixes apply to linux 3.2 on. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: <stable@vger.kernel.org> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
1 parent 7194efb commit 2830281

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

drivers/mmc/card/block.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -873,28 +873,34 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
873873
{
874874
struct mmc_blk_data *md = mq->data;
875875
struct mmc_card *card = md->queue.card;
876-
unsigned int from, nr, arg;
876+
unsigned int from, nr, arg, trim_arg, erase_arg;
877877
int err = 0, type = MMC_BLK_SECDISCARD;
878878

879879
if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
880880
err = -EOPNOTSUPP;
881881
goto out;
882882
}
883883

884+
from = blk_rq_pos(req);
885+
nr = blk_rq_sectors(req);
886+
884887
/* The sanitize operation is supported at v4.5 only */
885888
if (mmc_can_sanitize(card)) {
886-
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
887-
EXT_CSD_SANITIZE_START, 1, 0);
888-
goto out;
889+
erase_arg = MMC_ERASE_ARG;
890+
trim_arg = MMC_TRIM_ARG;
891+
} else {
892+
erase_arg = MMC_SECURE_ERASE_ARG;
893+
trim_arg = MMC_SECURE_TRIM1_ARG;
889894
}
890895

891-
from = blk_rq_pos(req);
892-
nr = blk_rq_sectors(req);
893-
894-
if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
895-
arg = MMC_SECURE_TRIM1_ARG;
896-
else
897-
arg = MMC_SECURE_ERASE_ARG;
896+
if (mmc_erase_group_aligned(card, from, nr))
897+
arg = erase_arg;
898+
else if (mmc_can_trim(card))
899+
arg = trim_arg;
900+
else {
901+
err = -EINVAL;
902+
goto out;
903+
}
898904
retry:
899905
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
900906
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -904,25 +910,41 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
904910
INAND_CMD38_ARG_SECERASE,
905911
0);
906912
if (err)
907-
goto out;
913+
goto out_retry;
908914
}
915+
909916
err = mmc_erase(card, from, nr, arg);
910-
if (!err && arg == MMC_SECURE_TRIM1_ARG) {
917+
if (err == -EIO)
918+
goto out_retry;
919+
if (err)
920+
goto out;
921+
922+
if (arg == MMC_SECURE_TRIM1_ARG) {
911923
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
912924
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
913925
INAND_CMD38_ARG_EXT_CSD,
914926
INAND_CMD38_ARG_SECTRIM2,
915927
0);
916928
if (err)
917-
goto out;
929+
goto out_retry;
918930
}
931+
919932
err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
933+
if (err == -EIO)
934+
goto out_retry;
935+
if (err)
936+
goto out;
920937
}
921-
out:
922-
if (err == -EIO && !mmc_blk_reset(md, card->host, type))
938+
939+
if (mmc_can_sanitize(card))
940+
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
941+
EXT_CSD_SANITIZE_START, 1, 0);
942+
out_retry:
943+
if (err && !mmc_blk_reset(md, card->host, type))
923944
goto retry;
924945
if (!err)
925946
mmc_blk_reset_success(md, type);
947+
out:
926948
spin_lock_irq(&md->lock);
927949
__blk_end_request(req, err, blk_rq_bytes(req));
928950
spin_unlock_irq(&md->lock);

drivers/mmc/core/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);
17021702

17031703
int mmc_can_sanitize(struct mmc_card *card)
17041704
{
1705+
if (!mmc_can_trim(card) && !mmc_can_erase(card))
1706+
return 0;
17051707
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
17061708
return 1;
17071709
return 0;

0 commit comments

Comments
 (0)