Re: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-30 Thread merez
Hi Ulf,

You are right, the caps2 flag for Sanitize can be removed.
I will send a fix for that.

Thanks,
Maya
> On 17 April 2013 13:38, Maya Erez  wrote:
>> 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.
>>
>> Signed-off-by: Yaniv Gardi 
>> Signed-off-by: Maya Erez 
>> ---
>>  drivers/mmc/card/block.c |   68
>> +++--
>>  drivers/mmc/card/queue.c |2 +-
>>  drivers/mmc/core/core.c  |   21 ++
>>  include/linux/mmc/core.h |2 +
>>  include/linux/mmc/host.h |1 +
>>  5 files changed, 72 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index e12a03c..1f043ee 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -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 24
>> +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF) >> 16)
>>
>>  #define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
>>   (req->cmd_flags & REQ_META)) && \
>> @@ -409,6 +411,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)
>>  {
>> @@ -511,6 +542,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, );
>>
>> if (cmd.error) {
>> @@ -940,10 +981,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 +992,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;
>> -   

Re: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-30 Thread merez
Hi Ulf,

You are right, the caps2 flag for Sanitize can be removed.
I will send a fix for that.

Thanks,
Maya
 On 17 April 2013 13:38, Maya Erez me...@codeaurora.org wrote:
 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.

 Signed-off-by: Yaniv Gardi yga...@codeaurora.org
 Signed-off-by: Maya Erez me...@codeaurora.org
 ---
  drivers/mmc/card/block.c |   68
 +++--
  drivers/mmc/card/queue.c |2 +-
  drivers/mmc/core/core.c  |   21 ++
  include/linux/mmc/core.h |2 +
  include/linux/mmc/host.h |1 +
  5 files changed, 72 insertions(+), 22 deletions(-)

 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index e12a03c..1f043ee 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -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 24
 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x  0x00FF)  16)

  #define mmc_req_rel_wr(req)(((req-cmd_flags  REQ_FUA) || \
   (req-cmd_flags  REQ_META))  \
 @@ -409,6 +411,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)
  {
 @@ -511,6 +542,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 +981,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 +992,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 = 

RE: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-18 Thread merez
Hi Luca,

See below (2 comments).

Thanks,
Maya
> Hi Maya,
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> ow...@vger.kernel.org] On Behalf Of Maya Erez
>> Sent: Wednesday, April 17, 2013 1:39 PM
>> To: linux-...@vger.kernel.org
>> Cc: linux-arm-...@vger.kernel.org; Maya Erez; Yaniv Gardi; open list
>> Subject: [PATCH v2] 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.
>>
>> Signed-off-by: Yaniv Gardi 
>> Signed-off-by: Maya Erez 
>> ---
>>  drivers/mmc/card/block.c |   68
>> +++---
>> ---
>>  drivers/mmc/card/queue.c |2 +-
>>  drivers/mmc/core/core.c  |   21 ++
>>  include/linux/mmc/core.h |2 +
>>  include/linux/mmc/host.h |1 +
>>  5 files changed, 72 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index e12a03c..1f043ee 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -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 24
>> +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF) >> 16)
>>
>>  #define mmc_req_rel_wr(req) (((req->cmd_flags & REQ_FUA) || \
>>(req->cmd_flags & REQ_META)) && \
>> @@ -409,6 +411,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)
>
> Shouldn't you set the sanitize_busy flag here in case of timeout error?
> Otherwise the patch looks good to me
>
> Thanks,
>Luca

This is done in __mmc_switch.
I sent an uncomplete patch by mistake. Good catch!

>
>> +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 +542,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, );
>>
>>  if (cmd.error) {
>> @@ -940,10 +981,10 @@ static int mmc_blk_issue_secdiscard_rq(struct
>> mmc_queue *mq,
>>  {
>>  struct mmc_blk_data *md = mq->data;
>>  struct mmc_card *card = 

RE: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-18 Thread merez
Hi Luca,

See below (2 comments).

Thanks,
Maya
 Hi Maya,

 -Original Message-
 From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
 ow...@vger.kernel.org] On Behalf Of Maya Erez
 Sent: Wednesday, April 17, 2013 1:39 PM
 To: linux-...@vger.kernel.org
 Cc: linux-arm-...@vger.kernel.org; Maya Erez; Yaniv Gardi; open list
 Subject: [PATCH v2] 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.

 Signed-off-by: Yaniv Gardi yga...@codeaurora.org
 Signed-off-by: Maya Erez me...@codeaurora.org
 ---
  drivers/mmc/card/block.c |   68
 +++---
 ---
  drivers/mmc/card/queue.c |2 +-
  drivers/mmc/core/core.c  |   21 ++
  include/linux/mmc/core.h |2 +
  include/linux/mmc/host.h |1 +
  5 files changed, 72 insertions(+), 22 deletions(-)

 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index e12a03c..1f043ee 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -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 24
 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x  0x00FF)  16)

  #define mmc_req_rel_wr(req) (((req-cmd_flags  REQ_FUA) || \
(req-cmd_flags  REQ_META))  \
 @@ -409,6 +411,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)

 Shouldn't you set the sanitize_busy flag here in case of timeout error?
 Otherwise the patch looks good to me

 Thanks,
Luca

This is done in __mmc_switch.
I sent an uncomplete patch by mistake. Good catch!


 +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 +542,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 +981,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 +992,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

RE: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Luca Porzio (lporzio)
Hi Maya,

> -Original Message-
> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
> ow...@vger.kernel.org] On Behalf Of Maya Erez
> Sent: Wednesday, April 17, 2013 1:39 PM
> To: linux-...@vger.kernel.org
> Cc: linux-arm-...@vger.kernel.org; Maya Erez; Yaniv Gardi; open list
> Subject: [PATCH v2] 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.
> 
> Signed-off-by: Yaniv Gardi 
> Signed-off-by: Maya Erez 
> ---
>  drivers/mmc/card/block.c |   68 +++---
> ---
>  drivers/mmc/card/queue.c |2 +-
>  drivers/mmc/core/core.c  |   21 ++
>  include/linux/mmc/core.h |2 +
>  include/linux/mmc/host.h |1 +
>  5 files changed, 72 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index e12a03c..1f043ee 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -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 24
> +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF) >> 16)
> 
>  #define mmc_req_rel_wr(req)  (((req->cmd_flags & REQ_FUA) || \
> (req->cmd_flags & REQ_META)) && \
> @@ -409,6 +411,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)

Shouldn't you set the sanitize_busy flag here in case of timeout error?
Otherwise the patch looks good to me.

Thanks,
   Luca

> + 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 +542,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, );
> 
>   if (cmd.error) {
> @@ -940,10 +981,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 +992,11 @@ static int mmc_blk_issue_secdiscard_rq(struct
> mmc_queue *mq,
>   from = blk_rq_pos(req);
>   nr = blk_rq_sectors(req);
> 
>

Re: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Ulf Hansson
On 17 April 2013 13:38, Maya Erez  wrote:
> 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.
>
> Signed-off-by: Yaniv Gardi 
> Signed-off-by: Maya Erez 
> ---
>  drivers/mmc/card/block.c |   68 +++--
>  drivers/mmc/card/queue.c |2 +-
>  drivers/mmc/core/core.c  |   21 ++
>  include/linux/mmc/core.h |2 +
>  include/linux/mmc/host.h |1 +
>  5 files changed, 72 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index e12a03c..1f043ee 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -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 24
> +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF) >> 16)
>
>  #define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
>   (req->cmd_flags & REQ_META)) && \
> @@ -409,6 +411,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)
>  {
> @@ -511,6 +542,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, );
>
> if (cmd.error) {
> @@ -940,10 +981,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 +992,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, 

[PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Maya Erez
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.

Signed-off-by: Yaniv Gardi 
Signed-off-by: Maya Erez 
---
 drivers/mmc/card/block.c |   68 +++--
 drivers/mmc/card/queue.c |2 +-
 drivers/mmc/core/core.c  |   21 ++
 include/linux/mmc/core.h |2 +
 include/linux/mmc/host.h |1 +
 5 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e12a03c..1f043ee 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -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 24
+#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF) >> 16)
 
 #define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
  (req->cmd_flags & REQ_META)) && \
@@ -409,6 +411,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)
 {
@@ -511,6 +542,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, );
 
if (cmd.error) {
@@ -940,10 +981,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 +992,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 +1032,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 

[PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Maya Erez
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.

Signed-off-by: Yaniv Gardi yga...@codeaurora.org
Signed-off-by: Maya Erez me...@codeaurora.org
---
 drivers/mmc/card/block.c |   68 +++--
 drivers/mmc/card/queue.c |2 +-
 drivers/mmc/core/core.c  |   21 ++
 include/linux/mmc/core.h |2 +
 include/linux/mmc/host.h |1 +
 5 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e12a03c..1f043ee 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -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 24
+#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x  0x00FF)  16)
 
 #define mmc_req_rel_wr(req)(((req-cmd_flags  REQ_FUA) || \
  (req-cmd_flags  REQ_META))  \
@@ -409,6 +411,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)
 {
@@ -511,6 +542,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 +981,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 +992,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 +1032,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:
   

Re: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Ulf Hansson
On 17 April 2013 13:38, Maya Erez me...@codeaurora.org wrote:
 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.

 Signed-off-by: Yaniv Gardi yga...@codeaurora.org
 Signed-off-by: Maya Erez me...@codeaurora.org
 ---
  drivers/mmc/card/block.c |   68 +++--
  drivers/mmc/card/queue.c |2 +-
  drivers/mmc/core/core.c  |   21 ++
  include/linux/mmc/core.h |2 +
  include/linux/mmc/host.h |1 +
  5 files changed, 72 insertions(+), 22 deletions(-)

 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index e12a03c..1f043ee 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -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 24
 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x  0x00FF)  16)

  #define mmc_req_rel_wr(req)(((req-cmd_flags  REQ_FUA) || \
   (req-cmd_flags  REQ_META))  \
 @@ -409,6 +411,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)
  {
 @@ -511,6 +542,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 +981,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 +992,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 +1032,6 @@ retry:
 goto out;
 }

 -  

RE: [PATCH v2] mmc: card: Adding support for sanitize in eMMC 4.5

2013-04-17 Thread Luca Porzio (lporzio)
Hi Maya,

 -Original Message-
 From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
 ow...@vger.kernel.org] On Behalf Of Maya Erez
 Sent: Wednesday, April 17, 2013 1:39 PM
 To: linux-...@vger.kernel.org
 Cc: linux-arm-...@vger.kernel.org; Maya Erez; Yaniv Gardi; open list
 Subject: [PATCH v2] 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.
 
 Signed-off-by: Yaniv Gardi yga...@codeaurora.org
 Signed-off-by: Maya Erez me...@codeaurora.org
 ---
  drivers/mmc/card/block.c |   68 +++---
 ---
  drivers/mmc/card/queue.c |2 +-
  drivers/mmc/core/core.c  |   21 ++
  include/linux/mmc/core.h |2 +
  include/linux/mmc/host.h |1 +
  5 files changed, 72 insertions(+), 22 deletions(-)
 
 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index e12a03c..1f043ee 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -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 24
 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x  0x00FF)  16)
 
  #define mmc_req_rel_wr(req)  (((req-cmd_flags  REQ_FUA) || \
 (req-cmd_flags  REQ_META))  \
 @@ -409,6 +411,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)

Shouldn't you set the sanitize_busy flag here in case of timeout error?
Otherwise the patch looks good to me.

Thanks,
   Luca

 + 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 +542,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 +981,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 +992,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