mmc: card: Adding support for sanitize in eMMC 4.5
Subsystems (2)
PATCH v4 1/1 mmc: card: Adding support for sanitize in eMMC 4.5
The sanitize support is added as a user-app ioctl call, and was removed from the block-device request, since its purpose is to be invoked not via File-System but by a user.
This feature deletes the unmap memory region of the eMMC card, by writing to a specific register in the EXT_CSD. unmap region is the memory region that was previously deleted (by erase, trim or discard operation).
In order to avoid timeout when sanitizing large-scale cards, the timeout for sanitize operation is 240 seconds.
--- drivers/mmc/card/block.c | 67 ++++++++++++++++++++++++++++++-------------- drivers/mmc/card/queue.c | 2 +- drivers/mmc/core/core.c | 22 ++++++++++++++ drivers/mmc/core/mmc_ops.c | 2 + include/linux/mmc/core.h | 2 + 5 files changed, 73 insertions(+), 22 deletions(-)
drivers/mmc/card/block.c +46 -21
@@ -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)) && \
@@ -409,6 +411,34 @@ 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)) { +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) {
@@ -511,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) {
@@ -940,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; }
@@ -951,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,
@@ -1003,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;
drivers/mmc/card/queue.c +1 -1
@@ -173,7 +173,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,/* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity =0 ; -if (mmc_can_secure_erase_trim (card) ||mmc_can_sanitize (card)) +if (mmc_can_secure_erase_trim (card))queue_flag_set_unlocked (QUEUE_FLAG_SECDISCARD , q); }
drivers/mmc/core/core.c +22 -0
@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host, context_info->is_done_rcv = false; context_info->is_new_req = false; cmd = mrq->cmd; +if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card)) { err = host->areq->err_check(host->card,
@@ -436,6 +437,27 @@ static void mmc_wait_for_req_done(struct mmc_host *host,wait_for_completion (&mrq->completion); cmd = mrq->cmd; + +/* +* If host has timed out waiting for the sanitize +* to complete, card might be still in programming state +* so let's try to bring the card out of programming +* state. +*/ +if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT ) { +if (!mmc_interrupt_hpi (host->card)) { +pr_warning ("%s: %s: Interrupted " +"sanitize\n" , +mmc_hostname (host), + __func__); + cmd->error =0 ; +break ; + }else { +pr_err ("%s: %s: Failed to interrupt " +"sanitize\n" , +mmc_hostname (host), __func__); + } + }if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card))break ;
drivers/mmc/core/mmc_ops.c +2 -0
@@ -431,6 +431,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, cmd.cmd_timeout_ms = timeout_ms; +if (index ==EXT_CSD_SANITIZE_START ) + cmd.sanitize_busy = true; err =mmc_wait_for_cmd (card->host, &cmd,MMC_CMD_RETRIES );if (err)
include/linux/mmc/core.h +2 -0
@@ -96,6 +96,8 @@ struct mmc_command {*/ unsigned int cmd_timeout_ms;/* in milliseconds */ +/* Set this flag only for blocking sanitize request */ +bool sanitize_busy;struct mmc_data *data;/* data segment associated with cmd */ struct mmc_request *mrq;/* associated request */
Signature · 4 lines
1.7.3.3 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Hi,
Ulf / Luca - I would appreciate if you could review this new version with high priority.
If you don't have additional concerns I would like to try and push the changes to kernel-3.10.
Thanks,
Maya
Quoted 236 lines
The sanitize support is added as a user-app ioctl call, and was removed from the block-device request, since its purpose is to be invoked not via File-System but by a user.
This feature deletes the unmap memory region of the eMMC card, by writing to a specific register in theEXT_CSD. unmap region is the memory region that was previously deleted (by erase, trim or discard operation).
In order to avoid timeout when sanitizing large-scale cards, the timeout for sanitize operation is 240 seconds.Signed-off-by Yaniv Gardi <[email protected]>Signed-off-by Maya Erez <[email protected]>--- drivers/mmc/card/block.c | 67 ++++++++++++++++++++++++++++++-------------- drivers/mmc/card/queue.c | 2 +- drivers/mmc/core/core.c | 22 ++++++++++++++ drivers/mmc/core/mmc_ops.c | 2 + include/linux/mmc/core.h | 2 + 5 files changed, 73 insertions(+), 22 deletions(-)drivers/mmc/card/block.c +2
-0@@ -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) || \drivers/mmc/card/block.c +28
-0(req->cmd_flags & REQ_META)) && \@@ -409,6 +411,34 @@ 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)) { +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){
drivers/mmc/card/block.c +10
-0@@ -511,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);drivers/mmc/card/block.c +2
-2if (cmd.error) {@@ -940,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;drivers/mmc/card/block.c +4
-16}@@ -951,23 +991,11 @@ static int mmc_blk_issue_secdiscard_rq(structmmc_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 ) {drivers/mmc/card/block.c +0
-3err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,@@ -1003,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;drivers/mmc/card/queue.c +1
-1@@ -173,7 +173,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,/* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity = 0; -if (mmc_can_secure_erase_trim (card) ||mmc_can_sanitize (card)) +if (mmc_can_secure_erase_trim (card))queue_flag_set_unlocked (QUEUE_FLAG_SECDISCARD , q); }drivers/mmc/core/core.c +1
-0@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host, context_info->is_done_rcv = false; context_info->is_new_req = false; cmd = mrq->cmd; +if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card)) {drivers/mmc/core/core.c +21
-0err = host->areq->err_check(host->card,@@ -436,6 +437,27 @@ static void mmc_wait_for_req_done(struct mmc_host *host,wait_for_completion (&mrq->completion); cmd = mrq->cmd; + +/* +* If host has timed out waiting for the sanitize +* to complete, card might be still in programming state +* so let's try to bring the card out of programming +* state. +*/ +if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT ) { +if (!mmc_interrupt_hpi (host->card)) { +pr_warning ("%s: %s: Interrupted " +"sanitize\n" , +mmc_hostname (host), + __func__); + cmd->error =0 ; +break ; + }else { +pr_err ("%s: %s: Failed to interrupt " +"sanitize\n" , +mmc_hostname (host), __func__); + } + }if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card))drivers/mmc/core/core.c +0
-0break ;drivers/mmc/core/mmc_ops.c +2
-0@@ -431,6 +431,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, cmd.cmd_timeout_ms = timeout_ms; +if (index ==EXT_CSD_SANITIZE_START ) + cmd.sanitize_busy = true; err =mmc_wait_for_cmd (card->host, &cmd,MMC_CMD_RETRIES );drivers/mmc/core/mmc_ops.c +0
-0if (err)include/linux/mmc/core.h +2
-1@@ -96,6 +96,8 @@ struct mmc_command {*/ unsigned int cmd_timeout_ms;/* in milliseconds */ +/* Set this flag only for blocking sanitize request */ +bool sanitize_busy;struct mmc_data *data;/* data segment associated with cmd */ struct mmc_request *mrq;/* associated request */ --1.7.3.3
--
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 3 lines
Maya Erez QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Maya,
This looks good to me.
Thanks,
Luca
Quoted 279 lines
-----Original Message-----
From: [email protected] [mailto:linux-mmc- [email protected]] On Behalf Of [email protected]
Sent: Wednesday, May 01, 2013 9:44 AM
To: Maya Erez
Cc: [email protected]; [email protected]; Maya Erez; Yaniv Gardi; open list
Subject: Re: [PATCH v4] mmc: card: Adding support for sanitize in eMMC 4.5Hi,
Ulf / Luca - I would appreciate if you could review this new version with
high priority.
If you don't have additional concerns I would like to try and push the changes to kernel-3.10.Thanks,
MayaQuoted 26 lines
The sanitize support is added as a user-app ioctl call, and was removed from the block-device request, since its purpose is to be invoked not via File-System but by a user.
This feature deletes the unmap memory region of the eMMC card, by writing to a specific register in theEXT_CSD. unmap region is the memory region that was previously deleted (by erase, trim or discard operation).
In order to avoid timeout when sanitizing large-scale cards, the timeout for sanitize operation is 240 seconds.Signed-off-by Yaniv Gardi <[email protected]>Signed-off-by Maya Erez <[email protected]>--- drivers/mmc/card/block.c | 67 ++++++++++++++++++++++++++++++-------------- drivers/mmc/card/queue.c | 2 +- drivers/mmc/core/core.c | 22 ++++++++++++++ drivers/mmc/core/mmc_ops.c | 2 + include/linux/mmc/core.h | 2 + 5 files changed, 73 insertions(+), 22 deletions(-)drivers/mmc/card/block.c +0
-0drivers/mmc/card/block.c MODULE_ALIAS("mmc:block"); · line 60
Quoted 3 lines
drivers/mmc/card/block.c +0
-0@@ -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
Quoted 44 lines
drivers/mmc/card/block.c +2
-0*/ +#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) || \drivers/mmc/card/block.c +28
-0(req->cmd_flags & REQ_META)) && \@@ -409,6 +411,34 @@ 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)) { +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,drivers/mmc/card/block.c +0
-0struct mmc_ioc_cmd __user *ic_ptr) {drivers/mmc/card/block.c static int mmc_blk_ioctl_cmd(struct block_device · line 545
Quoted 5 lines
drivers/mmc/card/block.c +1
-0@@ -511,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) {Quoted 13 lines
drivers/mmc/card/block.c +9
-0+ 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);drivers/mmc/card/block.c +0
-0if (cmd.error) {drivers/mmc/card/block.c static int mmc_blk_issue_secdiscard_rq(struct · line 947
Quoted 9 lines
drivers/mmc/card/block.c +1
-2@@ -940,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))){
Quoted 8 lines
drivers/mmc/card/block.c +1
-0+if (!(mmc_can_secure_erase_trim (card))) { err = -EOPNOTSUPP ; goto out;drivers/mmc/card/block.c +0
-0}@@ -951,23 +991,11 @@ static int mmc_blk_issue_secdiscard_rq(structmmc_queue *mq, from =blk_rq_pos (req); nr =blk_rq_sectors (req);drivers/mmc/card/block.c static int mmc_blk_issue_secdiscard_rq(struct · line 995
Quoted 10 lines
drivers/mmc/card/block.c +1
-8-/* 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))
drivers/mmc/core/core.c static int mmc_wait_for_data_req_done(struct
Quoted 44 lines
drivers/mmc/card/block.c +3
-8+ 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 ) {drivers/mmc/card/block.c +0
-3err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,@@ -1003,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;drivers/mmc/card/queue.c +1
-1@@ -173,7 +173,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,/* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity = 0; -if (mmc_can_secure_erase_trim (card) ||mmc_can_sanitize (card)) +if (mmc_can_secure_erase_trim (card))queue_flag_set_unlocked (QUEUE_FLAG_SECDISCARD , q); }drivers/mmc/core/core.c +0
-0@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct
mmc_hostdrivers/mmc/core/core.c static void mmc_wait_for_req_done(struct
Quoted 9 lines
drivers/mmc/core/core.c +1
-0*host, context_info->is_done_rcv = false; context_info->is_new_req = false; cmd = mrq->cmd; +if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card)) {drivers/mmc/core/core.c +0
-0err = host->areq->err_check(host->card,@@ -436,6 +437,27 @@ static void mmc_wait_for_req_done(struct
mmc_hostdrivers/mmc/core/mmc_ops.c int __mmc_switch(struct mmc_card *card, u8 set,
Quoted 33 lines
drivers/mmc/core/core.c +21
-0*host,wait_for_completion (&mrq->completion); cmd = mrq->cmd; + +/* +* If host has timed out waiting for the sanitize +* to complete, card might be still in programming state +* so let's try to bring the card out of programming +* state. +*/ +if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT ) { +if (!mmc_interrupt_hpi (host->card)) { +pr_warning ("%s: %s: Interrupted " +"sanitize\n" , +mmc_hostname (host), + __func__); + cmd->error =0 ; +break ; + }else { +pr_err ("%s: %s: Failed to interrupt " +"sanitize\n" , +mmc_hostname (host), __func__); + } + }if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card))drivers/mmc/core/core.c +0
-0break ;drivers/mmc/core/mmc_ops.c +0
-0@@ -431,6 +431,8 @@ int __mmc_switch(struct mmc_card *card, u8 set,u8
Quoted 14 lines
drivers/mmc/core/mmc_ops.c +2
-0index, u8 value, cmd.cmd_timeout_ms = timeout_ms; +if (index ==EXT_CSD_SANITIZE_START ) + cmd.sanitize_busy = true; err =mmc_wait_for_cmd (card->host, &cmd,MMC_CMD_RETRIES );drivers/mmc/core/mmc_ops.c +0
-0if (err)include/linux/mmc/core.h +0
-0include/linux/mmc/core.h struct mmc_command { · line 102
Quoted 7 lines
include/linux/mmc/core.h +2
-0@@ -96,6 +96,8 @@ struct mmc_command {*/ unsigned int cmd_timeout_ms;/* in milliseconds */ +/* Set this flag only for blocking sanitize request */ +bool sanitize_busy;struct mmc_data *data;/* data segment associated with cmd */
Quoted 5 lines
include/linux/mmc/core.h +0
-1struct mmc_request *mrq;/* associated request */ --1.7.3.3
--
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is amember
Quoted 4 lines
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc"in
Quoted 3 lines
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
Maya Erez
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Chris,
Can you please approve this patch and the corresponding mmc-utils patch?
Thanks,
Maya
Quoted 291 lines
Maya,
This looks good to me.
Thanks,
LucaQuoted 275 lines
-----Original Message-----
From: [email protected] [mailto:linux-mmc- [email protected]] On Behalf Of [email protected]
Sent: Wednesday, May 01, 2013 9:44 AM
To: Maya Erez
Cc: [email protected]; [email protected]; Maya Erez; Yaniv Gardi; open list
Subject: Re: [PATCH v4] mmc: card: Adding support for sanitize in eMMC 4.5Hi,
Ulf / Luca - I would appreciate if you could review this new version with
high priority.
If you don't have additional concerns I would like to try and push the changes to kernel-3.10.Thanks,
MayaQuoted 26 lines
The sanitize support is added as a user-app ioctl call, and was removed from the block-device request, since its purpose is to be invoked not via File-System but by a user.
This feature deletes the unmap memory region of the eMMC card, by writing to a specific register in theEXT_CSD. unmap region is the memory region that was previously deleted (by erase, trim or discard operation).
In order to avoid timeout when sanitizing large-scale cards, the timeout for sanitize operation is 240 seconds.Signed-off-by Yaniv Gardi <[email protected]>Signed-off-by Maya Erez <[email protected]>--- drivers/mmc/card/block.c | 67 ++++++++++++++++++++++++++++++-------------- drivers/mmc/card/queue.c | 2 +- drivers/mmc/core/core.c | 22 ++++++++++++++ drivers/mmc/core/mmc_ops.c | 2 + include/linux/mmc/core.h | 2 + 5 files changed, 73 insertions(+), 22 deletions(-)drivers/mmc/card/block.c +0
-0drivers/mmc/card/block.c MODULE_ALIAS("mmc:block"); · line 60
Quoted 3 lines
drivers/mmc/card/block.c +0
-0@@ -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
Quoted 44 lines
drivers/mmc/card/block.c +2
-0*/ +#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) || \drivers/mmc/card/block.c +28
-0(req->cmd_flags & REQ_META)) && \@@ -409,6 +411,34 @@ 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)) { +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,drivers/mmc/card/block.c +0
-0struct mmc_ioc_cmd __user *ic_ptr) {drivers/mmc/card/block.c static int mmc_blk_ioctl_cmd(struct block_device · line 545
Quoted 5 lines
drivers/mmc/card/block.c +1
-0@@ -511,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) {Quoted 13 lines
drivers/mmc/card/block.c +9
-0+ 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);drivers/mmc/card/block.c +0
-0if (cmd.error) {drivers/mmc/card/block.c static int mmc_blk_issue_secdiscard_rq(struct · line 947
Quoted 9 lines
drivers/mmc/card/block.c +1
-2@@ -940,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))){
Quoted 8 lines
drivers/mmc/card/block.c +1
-0+if (!(mmc_can_secure_erase_trim (card))) { err = -EOPNOTSUPP ; goto out;drivers/mmc/card/block.c +0
-0}@@ -951,23 +991,11 @@ static int mmc_blk_issue_secdiscard_rq(structmmc_queue *mq, from =blk_rq_pos (req); nr =blk_rq_sectors (req);drivers/mmc/card/block.c static int mmc_blk_issue_secdiscard_rq(struct · line 995
Quoted 10 lines
drivers/mmc/card/block.c +1
-8-/* 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))
drivers/mmc/core/core.c static int mmc_wait_for_data_req_done(struct
Quoted 44 lines
drivers/mmc/card/block.c +3
-8+ 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 ) {drivers/mmc/card/block.c +0
-3err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,@@ -1003,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;drivers/mmc/card/queue.c +1
-1@@ -173,7 +173,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,/* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity = 0; -if (mmc_can_secure_erase_trim (card) ||mmc_can_sanitize (card)) +if (mmc_can_secure_erase_trim (card))queue_flag_set_unlocked (QUEUE_FLAG_SECDISCARD , q); }drivers/mmc/core/core.c +0
-0@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct
mmc_hostdrivers/mmc/core/core.c static void mmc_wait_for_req_done(struct
Quoted 9 lines
drivers/mmc/core/core.c +1
-0*host, context_info->is_done_rcv = false; context_info->is_new_req = false; cmd = mrq->cmd; +if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card)) {drivers/mmc/core/core.c +0
-0err = host->areq->err_check(host->card,@@ -436,6 +437,27 @@ static void mmc_wait_for_req_done(struct
mmc_hostdrivers/mmc/core/mmc_ops.c int __mmc_switch(struct mmc_card *card, u8 set,
Quoted 33 lines
drivers/mmc/core/core.c +21
-0*host,wait_for_completion (&mrq->completion); cmd = mrq->cmd; + +/* +* If host has timed out waiting for the sanitize +* to complete, card might be still in programming state +* so let's try to bring the card out of programming +* state. +*/ +if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT ) { +if (!mmc_interrupt_hpi (host->card)) { +pr_warning ("%s: %s: Interrupted " +"sanitize\n" , +mmc_hostname (host), + __func__); + cmd->error =0 ; +break ; + }else { +pr_err ("%s: %s: Failed to interrupt " +"sanitize\n" , +mmc_hostname (host), __func__); + } + }if (!cmd->error || !cmd->retries ||mmc_card_removed (host->card))drivers/mmc/core/core.c +0
-0break ;drivers/mmc/core/mmc_ops.c +0
-0@@ -431,6 +431,8 @@ int __mmc_switch(struct mmc_card *card, u8 set,u8
Quoted 14 lines
drivers/mmc/core/mmc_ops.c +2
-0index, u8 value, cmd.cmd_timeout_ms = timeout_ms; +if (index ==EXT_CSD_SANITIZE_START ) + cmd.sanitize_busy = true; err =mmc_wait_for_cmd (card->host, &cmd,MMC_CMD_RETRIES );drivers/mmc/core/mmc_ops.c +0
-0if (err)include/linux/mmc/core.h +0
-0include/linux/mmc/core.h struct mmc_command { · line 102
Quoted 7 lines
include/linux/mmc/core.h +2
-0@@ -96,6 +96,8 @@ struct mmc_command {*/ unsigned int cmd_timeout_ms;/* in milliseconds */ +/* Set this flag only for blocking sanitize request */ +bool sanitize_busy;struct mmc_data *data;/* data segment associated with cmd */
Quoted 5 lines
include/linux/mmc/core.h +0
-1struct mmc_request *mrq;/* associated request */ --1.7.3.3
--
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is amember
Quoted 4 lines
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc"in
Quoted 3 lines
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
Maya Erez
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux FoundationQuoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 3 lines
Maya Erez QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation