|
@@ -58,6 +58,8 @@ MODULE_ALIAS("mmc:block");
|
|
|
#define INAND_CMD38_ARG_SECTRIM1 0x81
|
|
|
#define INAND_CMD38_ARG_SECTRIM2 0x88
|
|
|
#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
|
|
|
+#define MMC_SANITIZE_REQ_TIMEOUT 240000
|
|
|
+#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
|
|
|
|
|
|
#define mmc_req_rel_wr(req) (((req->cmd_flags & REQ_FUA) || \
|
|
|
(req->cmd_flags & REQ_META)) && \
|
|
@@ -408,6 +410,35 @@ static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static int ioctl_do_sanitize(struct mmc_card *card)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (!(mmc_can_sanitize(card) &&
|
|
|
+ (card->host->caps2 & MMC_CAP2_SANITIZE))) {
|
|
|
+ pr_warn("%s: %s - SANITIZE is not supported\n",
|
|
|
+ mmc_hostname(card->host), __func__);
|
|
|
+ err = -EOPNOTSUPP;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
|
|
|
+ mmc_hostname(card->host), __func__);
|
|
|
+
|
|
|
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
|
+ EXT_CSD_SANITIZE_START, 1,
|
|
|
+ MMC_SANITIZE_REQ_TIMEOUT);
|
|
|
+
|
|
|
+ if (err)
|
|
|
+ pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n",
|
|
|
+ mmc_hostname(card->host), __func__, err);
|
|
|
+
|
|
|
+ pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
|
|
|
+ __func__);
|
|
|
+out:
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static int mmc_blk_ioctl_cmd(struct block_device *bdev,
|
|
|
struct mmc_ioc_cmd __user *ic_ptr)
|
|
|
{
|
|
@@ -510,6 +541,16 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
|
|
|
goto cmd_rel_host;
|
|
|
}
|
|
|
|
|
|
+ if (MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) {
|
|
|
+ err = ioctl_do_sanitize(card);
|
|
|
+
|
|
|
+ if (err)
|
|
|
+ pr_err("%s: ioctl_do_sanitize() failed. err = %d",
|
|
|
+ __func__, err);
|
|
|
+
|
|
|
+ goto cmd_rel_host;
|
|
|
+ }
|
|
|
+
|
|
|
mmc_wait_for_req(card->host, &mrq);
|
|
|
|
|
|
if (cmd.error) {
|
|
@@ -939,10 +980,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
|
|
|
{
|
|
|
struct mmc_blk_data *md = mq->data;
|
|
|
struct mmc_card *card = md->queue.card;
|
|
|
- unsigned int from, nr, arg, trim_arg, erase_arg;
|
|
|
+ unsigned int from, nr, arg;
|
|
|
int err = 0, type = MMC_BLK_SECDISCARD;
|
|
|
|
|
|
- if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
|
|
|
+ if (!(mmc_can_secure_erase_trim(card))) {
|
|
|
err = -EOPNOTSUPP;
|
|
|
goto out;
|
|
|
}
|
|
@@ -950,23 +991,11 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
|
|
|
from = blk_rq_pos(req);
|
|
|
nr = blk_rq_sectors(req);
|
|
|
|
|
|
- /* The sanitize operation is supported at v4.5 only */
|
|
|
- if (mmc_can_sanitize(card)) {
|
|
|
- erase_arg = MMC_ERASE_ARG;
|
|
|
- trim_arg = MMC_TRIM_ARG;
|
|
|
- } else {
|
|
|
- erase_arg = MMC_SECURE_ERASE_ARG;
|
|
|
- trim_arg = MMC_SECURE_TRIM1_ARG;
|
|
|
- }
|
|
|
+ if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
|
|
|
+ arg = MMC_SECURE_TRIM1_ARG;
|
|
|
+ else
|
|
|
+ arg = MMC_SECURE_ERASE_ARG;
|
|
|
|
|
|
- if (mmc_erase_group_aligned(card, from, nr))
|
|
|
- arg = erase_arg;
|
|
|
- else if (mmc_can_trim(card))
|
|
|
- arg = trim_arg;
|
|
|
- else {
|
|
|
- err = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
retry:
|
|
|
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
|
|
|
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
@@ -1002,9 +1031,6 @@ retry:
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- if (mmc_can_sanitize(card))
|
|
|
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
|
- EXT_CSD_SANITIZE_START, 1, 0);
|
|
|
out_retry:
|
|
|
if (err && !mmc_blk_reset(md, card->host, type))
|
|
|
goto retry;
|