[PATCH v2] Fix for checking block numbers in disable emulation mode

2012-07-06 Thread Saugata Das
From: Saugata Das 

In 512B disable emulation patch, a check is done to ensure that size
of the data is multiple of 4KB within mmc_blk_issue_rw_rq. However,
the check is done with brq->data.blocks, which is not initialized at
the point of check. This is now changed to blk_rq_sectors.

In addition, when retrying read transfers, the current code retries
with single block. This has been changed to 8 blocks if disable
emulation is enabled.

For hosts which are not capable to handle transfer of multiple of 4KB,
a check has been added in mmc_read_ext_csd. A check has been added for
reliable write with EN_REL_WR=0, which is not allowed.

Signed-off-by: Saugata Das 

Changes in v2 :
- Added check in mmc_read_ext_csd
---
 drivers/mmc/card/block.c |   19 +--
 drivers/mmc/core/mmc.c   |9 +++--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index d628c5d..69b7b03 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1114,7 +1114,10 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
  (req->cmd_flags & REQ_META)) &&
(rq_data_dir(req) == WRITE) &&
-   (md->flags & MMC_BLK_REL_WR);
+   (md->flags & MMC_BLK_REL_WR) &&
+   ((card->ext_csd.data_sector_size == 512) ||
+((card->ext_csd.data_sector_size == 4096) &&
+ (card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)));
 
memset(brq, 0, sizeof(struct mmc_blk_request));
brq->mrq.cmd = &brq->cmd;
@@ -1145,7 +1148,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 * sectors can be read successfully.
 */
if (disable_multi)
-   brq->data.blocks = 1;
+   brq->data.blocks =
+   (card->ext_csd.data_sector_size == 4096) ?
+   8 : 1;
 
/* Some controllers can't do multiblock reads due to hw bugs */
if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&
@@ -1296,10 +1301,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
 * When 4KB native sector is enabled, only 8 blocks
 * multiple read or write is allowed
 */
-   if ((brq->data.blocks & 0x07) &&
+   if ((blk_rq_sectors(req) & 0x07) &&
(card->ext_csd.data_sector_size == 4096)) {
-   pr_err("%s: Transfer size is not 4KB sector 
size aligned\n",
-   req->rq_disk->disk_name);
+   pr_err("%s: Transfer size [%d] is not 4KB 
sector size aligned\n",
+   req->rq_disk->disk_name,
+   blk_rq_sectors(req));
goto cmd_abort;
}
mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
@@ -1364,7 +1370,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
/* Fall through */
}
case MMC_BLK_ECC_ERR:
-   if (brq->data.blocks > 1) {
+   if (brq->data.blocks >
+   (card->ext_csd.data_sector_size >> 9)) {
/* Redo read one sector at a time */
pr_warning("%s: retrying using single block 
read\n",
   req->rq_disk->disk_name);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 28fbd77..fb68f17 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -503,9 +503,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
 
-   if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+   if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) {
+   if ((card->host->caps2 & MMC_CAP2_NO_MULTI_READ) ||
+   (card->host->max_blk_count & 0x07)) {
+   err = -EINVAL;
+   goto out;
+   }
card->ext_csd.data_sector_size = 4096;
-   else
+   } else
card->ext_csd.data_sector_size = 512;
 
if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: core: Revert "skip card initialization if powerclass selection fails"

2012-07-02 Thread Saugata Das
On 2 July 2012 16:47, Marc Dietrich  wrote:
> Am Montag, 2. Juli 2012, 14:13:31 schrieb Saugata Das:
>> On 2 July 2012 12:26, Venkatraman S  wrote:
>> > This reverts commit 3d93576e(skip card initialization if
>> > power class selection fails).
>> > Problem has been reported when this is used with eMMC4.41
>> > card with Tegra Platform. Till the issue is root caused,
>> > bus width selection failure should not be treated as fatal.
>>
>> According to me, we need to find the root issue (which could be either
>> host not able to provide enough current or faulty eMMC). Do we know,
>> what could be the side effect of working on eMMC  with less power than
>> what it has requested in PWR_CL ?
>>
>> One known issue with the current power class selection is that we do
>> not check the current requirement for a selected power class. It
>> assumes that host is able to provide the maximum current needed at
>> highest speed (> 800mA). Is it already checked on Tegra ?
>
> Acording to the schematic, the emmc is "fused" with 150mA and 450mA. There are
> many supplies connected to it, so it is hard to tell what is the maximum, but
> certainly not 800 mA. Why do you think it should be such high? Powerclass "7"
> means 270 mA max and 160 mA RMS (dual voltage card). Btw, you may successfully
> google for the "schematic document" for this "paz00" board in question.
>

I was referring to maximum current as per 4.5 spec (power class 15). I
saw the logs which you sent earlier and the driver is trying to set
power class 3 (=> 180mA RMS / 280mA peak). May be, you can check the
regulators, if 450mA supply is enabled.


> Marc
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: core: Revert "skip card initialization if power class selection fails"

2012-07-02 Thread Saugata Das
On 2 July 2012 12:26, Venkatraman S  wrote:
> This reverts commit 3d93576e(skip card initialization if
> power class selection fails).
> Problem has been reported when this is used with eMMC4.41
> card with Tegra Platform. Till the issue is root caused,
> bus width selection failure should not be treated as fatal.
>

According to me, we need to find the root issue (which could be either
host not able to provide enough current or faulty eMMC). Do we know,
what could be the side effect of working on eMMC  with less power than
what it has requested in PWR_CL ?

One known issue with the current power class selection is that we do
not check the current requirement for a selected power class. It
assumes that host is able to provide the maximum current needed at
highest speed (> 800mA). Is it already checked on Tegra ?

> Reported-by: Marc Dietrich 
> Signed-Off-by: Venkatraman S 
> CC: Ulf Hansson 
> CC: Subhash Jadavani 
> CC: Saugata Das 
> ---
>  drivers/mmc/core/mmc.c | 18 +++---
>  1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 258b203..4f4489a 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -717,10 +717,6 @@ static int mmc_select_powerclass(struct mmc_card *card,
>  card->ext_csd.generic_cmd6_time);
> }
>
> -   if (err)
> -   pr_err("%s: power class selection for ext_csd_bus_width %d"
> -  " failed\n", mmc_hostname(card->host), bus_width);
> -
> return err;
>  }
>
> @@ -1104,7 +1100,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
> err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
> if (err)
> -   goto err;
> +   pr_warning("%s: power class selection to bus width %d"
> +  " failed\n", mmc_hostname(card->host),
> +  1 << bus_width);
> }
>
> /*
> @@ -1136,7 +1134,10 @@ static int mmc_init_card(struct mmc_host *host, u32 
> ocr,
> err = mmc_select_powerclass(card, 
> ext_csd_bits[idx][0],
> ext_csd);
> if (err)
> -   goto err;
> +   pr_warning("%s: power class selection to "
> +  "bus width %d failed\n",
> +  mmc_hostname(card->host),
> +  1 << bus_width);
>
> err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>  EXT_CSD_BUS_WIDTH,
> @@ -1164,7 +1165,10 @@ static int mmc_init_card(struct mmc_host *host, u32 
> ocr,
> err = mmc_select_powerclass(card, 
> ext_csd_bits[idx][1],
> ext_csd);
> if (err)
> -   goto err;
> +   pr_warning("%s: power class selection to "
> +  "bus width %d ddr %d failed\n",
> +  mmc_hostname(card->host),
> +  1 << bus_width, ddr);
>
> err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>  EXT_CSD_BUS_WIDTH,
> --
> 1.7.11.1.25.g0e18bef
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [MMC 4.5] Fix for checking block numbers in disable emulation mode

2012-06-29 Thread Saugata Das
On 29 June 2012 15:42, Seungwon Jeon  wrote:
> Hi Saugata,
>
> Could you check the comment below?
>
> Friday, June 29, 2012, Saugata Das  wrote:
>> From: Saugata Das 
>>
>> In 512B disable emulation patch, a check is done to ensure that size
>> of the data is multiple of 4KB. However, the check is done with
>> brq->data.blocks, which is not initialized at the point of check.
>> This is now changed to blk_rq_sectors.
>>
>> Signed-off-by: Saugata Das 
>> ---
>>  drivers/mmc/card/block.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index d628c5d..ee8b3d6 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -1296,7 +1296,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
>> struct request *rqc)
>>                        * When 4KB native sector is enabled, only 8 blocks
>>                        * multiple read or write is allowed
>>                        */
>> -                     if ((brq->data.blocks & 0x07) &&
>> +                     if ((blk_rq_sectors(req) & 0x07) &&
>>                               (card->ext_csd.data_sector_size == 4096)) {
>>                               pr_err("%s: Transfer size is not 4KB sector 
>> size aligned\n",
>>                                       req->rq_disk->disk_name);
>
> In current error handling, multiple block read can be retried using single 
> block read
> with disable_multi. Then 4KB alignment will be broken.

True. I shall change to something like,

if (disable_multi)
-   brq->data.blocks = 1;
+   brq->data.blocks =
+   (card->ext_csd.data_sector_size == 4096) ?
+   8 : 1;


> Also,  there is some conditions to modify the number of blocks in 
> mmc_blk_rw_rq_prep.
> That means the alignment of blocks can be changed after mmc_blk_rw_rq_prep.
> It needs to be considered.

I think you are referring to possibilities where host is not able to
transfer in multiple of 4KB (MMC_CAP2_NO_MULTI_READ is enabled or
host->max_blk_count is not multiple of 8). I shall add a check in
mmc_read_ext_csd.


-   if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+   if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) {
+   if ((card->host->caps2 & MMC_CAP2_NO_MULTI_READ) ||
+   (card->host->max_blk_count & 0x07)) {
+   err = -EINVAL;
+   goto out;
+   }


>
> And I have a question.
> Spec mentioned that arguments for read commands (CMD17/18) shall always be 
> aligned to 8(4KB)
> in Native 4KB sector. In current implementation CMD17/18 is only used when 
> data.blocks is 1.
> If data.blocks is 8 in Native 4KB sector, then CMD17/18 should be taken 
> instead of CMD24/25?

In native sector mode, only CMD18 and CMD25 will be used for read and write.


>
> Thanks,
> Seungwon Jeon
>> --
>> 1.7.4.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] MMC-4.5 Power OFF Notify Rework

2012-06-29 Thread Saugata Das
From: Saugata Das 

This is a rework of the existing POWER OFF NOTIFY patch. The CMD0 based
reinitialization of the eMMC during mmc_resume is introduced back. Function
poweroff_notify has been added as a bus_ops (as desired by the reviewers on
a previous version of the patch). Removed the configuration of notify type
("power_notify_type") from the host drivers. This is now passed as parameter
to poweroff_notify.

Signed-off-by: Saugata Das 
Signed-off-by: Girish K S 
Signed-off-by: Asutosh Das 
---
 drivers/mmc/core/core.c   |  108 ++--
 drivers/mmc/core/core.h   |1 +
 drivers/mmc/core/mmc.c|   44 +++---
 drivers/mmc/host/dw_mmc.c |5 --
 drivers/mmc/host/sdhci.c  |9 
 include/linux/mmc/card.h  |5 +-
 include/linux/mmc/core.h  |1 +
 include/linux/mmc/host.h  |4 --
 include/linux/mmc/mmc.h   |7 +++
 9 files changed, 92 insertions(+), 92 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b6141d..fe616b9 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1101,48 +1101,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned 
int drv_type)
mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-   struct mmc_card *card;
-   unsigned int timeout;
-   unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-   int err = 0;
-
-   card = host->card;
-   mmc_claim_host(host);
-
-   /*
-* Send power notify command only if card
-* is mmc and notify state is powered ON
-*/
-   if (card && mmc_card_mmc(card) &&
-   (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-   if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-   notify_type = EXT_CSD_POWER_OFF_SHORT;
-   timeout = card->ext_csd.generic_cmd6_time;
-   card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-   } else {
-   notify_type = EXT_CSD_POWER_OFF_LONG;
-   timeout = card->ext_csd.power_off_longtime;
-   card->poweroff_notify_state = MMC_POWEROFF_LONG;
-   }
-
-   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_POWER_OFF_NOTIFICATION,
-notify_type, timeout);
-
-   if (err && err != -EBADMSG)
-   pr_err("Device failed to respond within %d poweroff "
-  "time. Forcefully powering down the device\n",
-  timeout);
-
-   /* Set the card state to no notification after the poweroff */
-   card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
-   }
-   mmc_release_host(host);
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1202,8 +1160,6 @@ static void mmc_power_up(struct mmc_host *host)
 
 void mmc_power_off(struct mmc_host *host)
 {
-   int err = 0;
-
if (host->ios.power_mode == MMC_POWER_OFF)
return;
 
@@ -1212,22 +1168,6 @@ void mmc_power_off(struct mmc_host *host)
host->ios.clock = 0;
host->ios.vdd = 0;
 
-   /*
-* For eMMC 4.5 device send AWAKE command before
-* POWER_OFF_NOTIFY command, because in sleep state
-* eMMC 4.5 devices respond to only RESET and AWAKE cmd
-*/
-   if (host->card && mmc_card_is_sleep(host->card) &&
-   host->bus_ops->resume) {
-   err = host->bus_ops->resume(host);
-
-   if (!err)
-   mmc_poweroff_notify(host);
-   else
-   pr_warning("%s: error %d during resume "
-  "(continue with poweroff sequence)\n",
-  mmc_hostname(host), err);
-   }
 
/*
 * Reset ocr mask to be the highest possible voltage supported for
@@ -1726,6 +1666,15 @@ int mmc_can_secure_erase_trim(struct mmc_card *card)
 }
 EXPORT_SYMBOL(mmc_can_secure_erase_trim);
 
+int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+   return card &&
+   mmc_card_mmc(card) &&
+   card->host->bus_ops->poweroff_notify &&
+   (card->poweroff_notify_state == MMC_POWERED_ON);
+}
+EXPORT_SYMBOL(mmc_can_poweroff_notify);
+
 int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
unsigned int nr)
 {
@@ -2096,6 +2045,15 @@ void mmc_stop_host(struct mmc_host *host)
 
mmc_bus_get(host);
if (host->bus_ops &&am

[PATCH] [MMC 4.5] Fix for checking block numbers in disable emulation mode

2012-06-28 Thread Saugata Das
From: Saugata Das 

In 512B disable emulation patch, a check is done to ensure that size
of the data is multiple of 4KB. However, the check is done with
brq->data.blocks, which is not initialized at the point of check.
This is now changed to blk_rq_sectors.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index d628c5d..ee8b3d6 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1296,7 +1296,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
 * When 4KB native sector is enabled, only 8 blocks
 * multiple read or write is allowed
 */
-   if ((brq->data.blocks & 0x07) &&
+   if ((blk_rq_sectors(req) & 0x07) &&
(card->ext_csd.data_sector_size == 4096)) {
pr_err("%s: Transfer size is not 4KB sector 
size aligned\n",
req->rq_disk->disk_name);
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RESEND v7 2/3] mmc: core: Support packed write command for eMMC4.5 device

2012-06-26 Thread Saugata Das
On 26 June 2012 09:18, Seungwon Jeon  wrote:
> Hi Subhash,
>
> Subhash Jadavani  wrote:
>> Hi Seungwon,
>>
>> Please one comment inline below related to large sector size handling for 
>> packed commands.
>>
>> Regards,
>> Subhash
>>
>> > -Original Message-
>> > From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> > ow...@vger.kernel.org] On Behalf Of Seungwon Jeon
>> > Sent: Monday, June 18, 2012 11:13 AM
>> > To: linux-mmc@vger.kernel.org
>> > Cc: linux-ker...@vger.kernel.org; 'Chris Ball'; 'Maya Erez'; 'Subhash 
>> > Jadavani';
>> > 'S, Venkatraman'
>> > Subject: [PATCH RESEND v7 2/3] mmc: core: Support packed write command
>> > for eMMC4.5 device
>> >
>> > This patch supports packed write command of eMMC4.5 device.
>> > Several writes can be grouped in packed command and all data of the
>> > individual commands can be sent in a single transfer on the bus.
>> >
>> > Signed-off-by: Seungwon Jeon 
>> > ---
>> >  drivers/mmc/card/block.c   |  406
>> > +---
>> >  drivers/mmc/card/queue.c   |   45 +-
>> >  drivers/mmc/card/queue.h   |   12 ++
>> >  drivers/mmc/core/mmc_ops.c |    1 +
>> >  include/linux/mmc/core.h   |    4 +
>> >  5 files changed, 441 insertions(+), 27 deletions(-)
>> >
>> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index
>> > 7e3f453..eb99e35 100644
>> > --- a/drivers/mmc/card/block.c
>> > +++ b/drivers/mmc/card/block.c
>> > @@ -58,6 +58,12 @@ MODULE_ALIAS("mmc:block");  #define
>> > INAND_CMD38_ARG_SECTRIM1 0x81  #define INAND_CMD38_ARG_SECTRIM2
>> > 0x88
>> >
>> > +#define mmc_req_rel_wr(req)        (((req->cmd_flags & REQ_FUA) || \
>> > +                   (req->cmd_flags & REQ_META)) && \
>> > +                   (rq_data_dir(req) == WRITE))
>> > +#define PACKED_CMD_VER             0x01
>> > +#define PACKED_CMD_WR              0x02
>> > +
>> >  static DEFINE_MUTEX(block_mutex);
>> >
>> >  /*
>> > @@ -123,9 +129,21 @@ enum mmc_blk_status {
>> >     MMC_BLK_NOMEDIUM,
>> >  };
>> >
>> > +enum {
>> > +   MMC_PACKED_N_IDX = -1,
>> > +   MMC_PACKED_N_ZERO,
>> > +   MMC_PACKED_N_SINGLE,
>> > +};
>> > +
>> >  module_param(perdev_minors, int, 0444);
>> > MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per
>> > device");
>> >
>> > +static inline void mmc_blk_clear_packed(struct mmc_queue_req *mqrq) {
>> > +   mqrq->packed_cmd = MMC_PACKED_NONE;
>> > +   mqrq->packed_num = MMC_PACKED_N_ZERO;
>> > +}
>> > +
>> >  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)  {
>> >     struct mmc_blk_data *md;
>> > @@ -1081,12 +1099,61 @@ static int mmc_blk_err_check(struct mmc_card
>> > *card,
>> >     if (!brq->data.bytes_xfered)
>> >             return MMC_BLK_RETRY;
>> >
>> > +   if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
>> > +           if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
>> > +                   return MMC_BLK_PARTIAL;
>> > +           else
>> > +                   return MMC_BLK_SUCCESS;
>> > +   }
>> > +
>> >     if (blk_rq_bytes(req) != brq->data.bytes_xfered)
>> >             return MMC_BLK_PARTIAL;
>> >
>> >     return MMC_BLK_SUCCESS;
>> >  }
>> >
>> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
>> > +                               struct mmc_async_req *areq)
>> > +{
>> > +   struct mmc_queue_req *mq_rq = container_of(areq, struct
>> > mmc_queue_req,
>> > +                   mmc_active);
>> > +   struct request *req = mq_rq->req;
>> > +   int err, check, status;
>> > +   u8 ext_csd[512];
>> > +
>> > +   mq_rq->packed_retries--;
>> > +   check = mmc_blk_err_check(card, areq);
>> > +   err = get_card_status(card, &status, 0);
>> > +   if (err) {
>> > +           pr_err("%s: error %d sending status command\n",
>> > +                           req->rq_disk->disk_name, err);
>> > +           return MMC_BLK_ABORT;
>> > +   }
>> > +
>> > +   if (status & R1_EXP_EVENT) {
>> > +           err = mmc_send_ext_csd(card, ext_csd);
>> > +           if (err) {
>> > +                   pr_err("%s: error %d sending ext_csd\n",
>> > +                                   req->rq_disk->disk_name, err);
>> > +                   return MMC_BLK_ABORT;
>> > +           }
>> > +
>> > +           if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] &
>> > +                                   EXT_CSD_PACKED_FAILURE) &&
>> > +                           (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
>> > +                            EXT_CSD_PACKED_GENERIC_ERROR)) {
>> > +                   if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
>> > +                                   EXT_CSD_PACKED_INDEXED_ERROR) {
>> > +                           mq_rq->packed_fail_idx =
>> > +                             ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] -
>> > 1;
>> > +                           return MMC_BLK_PARTIAL;
>> > +                   }
>> > +           }
>> > +   }
>> > +
>> > +   return check;
>> > +}
>> > +
>> >  static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
>> >                            struct mmc_

Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-06-15 Thread Saugata Das
On 15 June 2012 16:56, Ulf Hansson  wrote:
> Hi Saugata,
>
> snip.
>
>
>>
>> The problem in sending CMD0 without power OFF notify is possibility of
>> some data loss in MMC-4.5 devices.
>
>
>
> I don't see the problem here. You will be sending power OFF notify when
> you
> can. The only difference is when you "wake" the device from sleep mode.
> Instead of using CMD5, which may work is some cases and in some cases
> not
> (without restoring ios). So using CMD0 as common way of waking up from
> suspend should be fine. Unless I missed something of course. :-)
>

 CMD0 is a reset. I expect with power OFF notify enable, the eMMC
 device will postpone some control information update to its internal
 non-volatile memory (e.g. some data structures which are kept in the
 controller buffers and not stored in NAND). If we do a CMD0, then the
 eMMC device will be reset and we may lose some data. In addition to
 that, doing complete card initialization will increase the wakeup time
 (for 4.4 devices).
>
>
> When doing poweroff_notify at suspend you have _always_ cut both vcc and
> vccq, according to MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which means you
> must always use CMD0 to wake up. There is no present internal cache in the
> eMMC here.
>
> In sleep mode, you can use CMD5, but until the poweroff notify patches (the
> patch that broke suspend/resume, not this one), we have used CMD0 to wake
> up. Let's go back to that solution. Then we can address you concern about
> "data loss" for sleep mode in separate patch.
>

Yes, you will get back to the same code flow with the introduction of
the MMC_CAP2_NO_INIT_ON_RESUME. If some host drivers are capable of
executing the CMD5 resume then they enable this cap and go on the
optimized path. The rest go on CMD0 path.

>

 Till now, we have done complete card initialization during resume
>>>
>>> Yes, me and Ulf think we should still do a complete initialization, at
>>> least for now and in this patch.
>>>
>>
>> In my opinion, that's incorrect on MMC-4.5 device and unoptimized for
>> MMC-4.41 device.
>
>
> Unoptimized for 4.41 with sleep, might be correct. But, again, let's look
> into that in a second step.
>
> As stated for 4.5 devices with poweroff_notify, there are no issues.
>
>>
>> Let me propose a new cap, MMC_CAP2_NO_INIT_ON_RESUME and do something
>> like following in mmc_resume,
>>
>>        mmc_claim_host(host);
>> -       if (mmc_card_is_sleep(host->card)) {
>> +       if (mmc_card_is_sleep(host->card)&&
>> +               (host->caps2&  MMC_CAP2_NO_INIT_ON_RESUME)) {
>>                mmc_restore_ios(host,&host->saved_ios);
>>
>>                err = mmc_card_awake(host);
>>        } else
>>                err = mmc_init_card(host, host->ocr, host->card);
>>
>> I hope it's OK for Ulf, Per, Subhash, Girish, Asutosh.
>>
>>
>>> A separate patch may deal with resume awake CMD5 and IOS save/restore.
>>>
>>> We may also discuss a clean up patch later on to reduce the number of
>>> bus_ops. Sleep, awake, and poweroff_notify are MMC specific.
>>> power_save/power_restore maps to suspend/resume. But let's not discuss
>>> this now :)
>>>
>>> BR
>>> Per
>
>
>
> Kind regards
> Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-06-15 Thread Saugata Das
On 15 June 2012 15:22, Per Forlin  wrote:
> On Fri, Jun 15, 2012 at 10:34 AM, Saugata Das  wrote:
>> On 15 June 2012 12:52, Ulf Hansson  wrote:
>>> On 06/15/2012 05:49 AM, Saugata Das wrote:
>>>>
>>>> On 15 June 2012 00:36, Per Forlin  wrote:
>>>>>
>>>>> Hi Saugata,
>>>>>
>>>>> I can have a go and test it. But first I would like to bring up 3
>>>>> concerns that I have with this patch.
>>>>>
>>>>> 1. This patch should be sent to cc-stable in order to repair the bug
>>>>> introduced in 3.4
>>>>
>>>>
>>>> I shall sent it out today.
>>>>
>>>>> 2. Is the bus_ops for poweroff_notify really necessary since only mmc
>>>>> use it?
>>>>
>>>>
>>>> This was recommended in the review from Ulf. If it is not adding to a
>>>> bug, I propose to keep it this way. Otherwise, we will be going in
>>>> circles :-)
>>>
>>>
>>> Moreover it seems close related to sleep, which is implemented with bus_ops.
>>> So I would say, keep as is. We might change later, then both sleep and
>>> poweroff_notify together.
>>>
>>>>
>>>>> There are already bus_ops for suspend/resume,
>>>>> power_save/power_restore and remove. It feels like it would be
>>>>> possible to address poweroff_notify internally from mmc.c from theses
>>>>> bus_ops. I would be nice to add this feature without having to touch
>>>>> core.c.
>>>>>
>>>>> For instance. Call mmc_suspend() from mmc_remove()
>>>>> +++ b/drivers/mmc/core/mmc.c
>>>>> @@ -1302,7 +1302,7 @@ static void mmc_remove(struct mmc_host *host)
>>>>> +       __mmc_suspend(host, true);
>>>>>        mmc_remove_card(host->card);
>>>>>
>>>>> @@ -1347,7 +1347,7 @@ static void mmc_detect(struct mmc_host *host)
>>>>> -static int mmc_suspend(struct mmc_host *host)
>>>>> +static int __mmc_suspend(struct mmc_host *host, bool remove)
>>>>>
>>>>> @@ -1356,7 +1356,8 @@ static int mmc_suspend(struct mmc_host *host)
>>>>>        mmc_claim_host(host);
>>>>>        if (mmc_can_poweroff_notify(host->card)&&
>>>>> -               (host->caps2&  MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND)) {
>>>>> +               (host->caps2&  MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND ||
>>>>>
>>>>> +                remove)) {
>>>>>                err = mmc_poweroff_notify(host, MMC_PW_OFF_NOTIFY_SHORT);
>>>>>        } else {
>>>>>                if (mmc_card_can_sleep(host))
>>>>>
>>>>> @@ -1372,6 +1373,11 @@ static int mmc_suspend(struct mmc_host *host)
>>>>> +static int mmc_suspend(struct mmc_host *host)
>>>>> +{
>>>>> +       return __mmc_suspend(host, false);
>>>>> +}
>>>>> +
>>>>>
>>>>> Calling mmc_suspend from mmc_remove() has another advantage since it
>>>>> may issue SLEEP (CMD5) before the card is removed and power off. This
>>>>> is recommended by eMMC Vendors in order to shutdown the eMMC safely to
>>>>> prevent data corruption. When the platform shuts down the power to the
>>>>> eMMC will be turned off no matter what.
>>>>
>>>>
>>>> May be for MMC-4.41 cards this approach can be taken. For MMC-4.5, it
>>>> has to be power OFF notify when the power is removed. Lets do it for
>>>> another patch, since the intention of this patch is to fix the issues
>>>> around power OFF notify.
>>>
>>>
>>> I agree with you Saugata, the exact same sequence as in suspend can not be
>>> used. The reason is simply that we do not want to consider
>>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND for doing poweroff_notify here, as we
>>> want in suspend.
>>>
>>> Leave this to be fixed in a separate patch instead.
>>>
>>>
>>>>
>>>>>
>>>>> 3. About the sleep and awake issue. This is not really related to
>>>>> poweroff_notify() as I see it. I would recommend to use CMD 0 to
>>>>> re-init the card safely after sleep in this patch. Then you could send
>>>>> out a sleep/awake patch that address this separately.  This would also
>>>>> make #1 easi

Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-06-15 Thread Saugata Das
On 15 June 2012 12:52, Ulf Hansson  wrote:
> On 06/15/2012 05:49 AM, Saugata Das wrote:
>>
>> On 15 June 2012 00:36, Per Forlin  wrote:
>>>
>>> Hi Saugata,
>>>
>>> I can have a go and test it. But first I would like to bring up 3
>>> concerns that I have with this patch.
>>>
>>> 1. This patch should be sent to cc-stable in order to repair the bug
>>> introduced in 3.4
>>
>>
>> I shall sent it out today.
>>
>>> 2. Is the bus_ops for poweroff_notify really necessary since only mmc
>>> use it?
>>
>>
>> This was recommended in the review from Ulf. If it is not adding to a
>> bug, I propose to keep it this way. Otherwise, we will be going in
>> circles :-)
>
>
> Moreover it seems close related to sleep, which is implemented with bus_ops.
> So I would say, keep as is. We might change later, then both sleep and
> poweroff_notify together.
>
>>
>>> There are already bus_ops for suspend/resume,
>>> power_save/power_restore and remove. It feels like it would be
>>> possible to address poweroff_notify internally from mmc.c from theses
>>> bus_ops. I would be nice to add this feature without having to touch
>>> core.c.
>>>
>>> For instance. Call mmc_suspend() from mmc_remove()
>>> +++ b/drivers/mmc/core/mmc.c
>>> @@ -1302,7 +1302,7 @@ static void mmc_remove(struct mmc_host *host)
>>> +       __mmc_suspend(host, true);
>>>        mmc_remove_card(host->card);
>>>
>>> @@ -1347,7 +1347,7 @@ static void mmc_detect(struct mmc_host *host)
>>> -static int mmc_suspend(struct mmc_host *host)
>>> +static int __mmc_suspend(struct mmc_host *host, bool remove)
>>>
>>> @@ -1356,7 +1356,8 @@ static int mmc_suspend(struct mmc_host *host)
>>>        mmc_claim_host(host);
>>>        if (mmc_can_poweroff_notify(host->card)&&
>>> -               (host->caps2&  MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND)) {
>>> +               (host->caps2&  MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND ||
>>>
>>> +                remove)) {
>>>                err = mmc_poweroff_notify(host, MMC_PW_OFF_NOTIFY_SHORT);
>>>        } else {
>>>                if (mmc_card_can_sleep(host))
>>>
>>> @@ -1372,6 +1373,11 @@ static int mmc_suspend(struct mmc_host *host)
>>> +static int mmc_suspend(struct mmc_host *host)
>>> +{
>>> +       return __mmc_suspend(host, false);
>>> +}
>>> +
>>>
>>> Calling mmc_suspend from mmc_remove() has another advantage since it
>>> may issue SLEEP (CMD5) before the card is removed and power off. This
>>> is recommended by eMMC Vendors in order to shutdown the eMMC safely to
>>> prevent data corruption. When the platform shuts down the power to the
>>> eMMC will be turned off no matter what.
>>
>>
>> May be for MMC-4.41 cards this approach can be taken. For MMC-4.5, it
>> has to be power OFF notify when the power is removed. Lets do it for
>> another patch, since the intention of this patch is to fix the issues
>> around power OFF notify.
>
>
> I agree with you Saugata, the exact same sequence as in suspend can not be
> used. The reason is simply that we do not want to consider
> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND for doing poweroff_notify here, as we
> want in suspend.
>
> Leave this to be fixed in a separate patch instead.
>
>
>>
>>>
>>> 3. About the sleep and awake issue. This is not really related to
>>> poweroff_notify() as I see it. I would recommend to use CMD 0 to
>>> re-init the card safely after sleep in this patch. Then you could send
>>> out a sleep/awake patch that address this separately.  This would also
>>> make #1 easier, send patch to cc-stable. Adding save/restore IOS is a
>>> new feature and should not be sent to the cc-stable list. What do you
>>> think?
>>
>>
>> The problem in sending CMD0 without power OFF notify is possibility of
>> some data loss in MMC-4.5 devices.
>
>
> I don't see the problem here. You will be sending power OFF notify when you
> can. The only difference is when you "wake" the device from sleep mode.
> Instead of using CMD5, which may work is some cases and in some cases not
> (without restoring ios). So using CMD0 as common way of waking up from
> suspend should be fine. Unless I missed something of course. :-)
>

CMD0 is a reset. I expect with power OFF notify enable, the eMMC
device will postpone some control information update to its internal
non-volatile memory (e.g. some data structures which are kept in the
controller buffers and not stored in NAND). If we do a CMD0, then the
eMMC device will be reset and we may lose some data. In addition to
that, doing complete card initialization will increase the wakeup time
(for 4.4 devices).

Till now, we have done complete card initialization during resume and
not done a real resume. I am not sure, if this patch is exposing some
host drivers issue now. So, please check the drivers as well.


> Kind regards
> Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] MMC-4.5 Power OFF Notify Rework

2012-06-14 Thread Saugata Das
From: Saugata Das 

This is a rework of the existing POWER OFF NOTIFY patch. The current problem
with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
power_mode from mmc_set_ios in different host controller drivers.

This new patch works around this problem by adding a new host CAP,
MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that host
controller drivers will set this CAP, if they switch off both Vcc and Vccq
from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.

This patch also sends POWER OFF NOTIFY from power management routines (e.g.
mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host), which
does reinitialization of the eMMC on the return path of the power management
routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
mmc_start_host).

This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent from
the suspend sequence. If it is sent from shutdown sequence then it is set to
POWER_OFF_LONG.

Earlier implementation of PowerOff Notify as a core function is replaced as
a device's bus operation.

For the cards that cannot cut vccq can sleep during suspend. But the after
suspend->sleep->poweroff the ios values are modified. which results in
malfunction of card after resume. This patch fixes that issue by saving the
ios before sleep and restoring the saved values before resume.

Signed-off-by: Saugata Das 
Signed-off-by: Girish K S 
Signed-off-by: Asutosh Das 
Reviewed-by: Subhash Jadavani 

changes in v6:
-save/restore ios during suspend/resume
changes in v5:
modified the the handling of return value in mmc_poweroff_notify.
changes in v4:
As suggested in review,
- Moved mmc_can_poweroff_notify to core.c
- Moved mmc_claim_host, mmc_release_host outside mmc_poweroff_notify
- Added check for wrong initialization for poweroff_notify_type
- mmc_poweroff_notify is modified to take as 2nd parameter
changes in v3:
This version addresses the review comments given by Subhash and Ulf
changes in v2:
This version addresses the changes suggested by Ulf
---
 drivers/mmc/core/core.c   |  127 ++---
 drivers/mmc/core/core.h   |3 +
 drivers/mmc/core/mmc.c|   58 ++---
 drivers/mmc/host/dw_mmc.c |5 --
 drivers/mmc/host/sdhci.c  |9 ---
 include/linux/mmc/card.h  |5 +-
 include/linux/mmc/core.h  |1 +
 include/linux/mmc/host.h  |6 +--
 include/linux/mmc/mmc.h   |7 +++
 9 files changed, 128 insertions(+), 93 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b6141d..6f68aad 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -734,6 +734,25 @@ void mmc_set_chip_select(struct mmc_host *host, int mode)
 }
 
 /*
+ * used to save the ios before suspend.
+ */
+void mmc_save_ios(struct mmc_host *host, struct mmc_ios *ios)
+{
+   mmc_host_clk_hold(host);
+   memcpy(&host->saved_ios, ios, sizeof(struct mmc_ios));
+   mmc_host_clk_release(host);
+}
+
+/*
+ * Restore the saved ios.
+ */
+void mmc_restore_ios(struct mmc_host *host, struct mmc_ios *saved_ios)
+{
+   memcpy(&host->ios, saved_ios, sizeof(struct mmc_ios));
+   mmc_set_ios(host);
+}
+
+/*
  * Sets the host clock to the highest possible frequency that
  * is below "hz".
  */
@@ -1101,48 +1120,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned 
int drv_type)
mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-   struct mmc_card *card;
-   unsigned int timeout;
-   unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-   int err = 0;
-
-   card = host->card;
-   mmc_claim_host(host);
-
-   /*
-* Send power notify command only if card
-* is mmc and notify state is powered ON
-*/
-   if (card && mmc_card_mmc(card) &&
-   (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-   if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-   notify_type = EXT_CSD_POWER_OFF_SHORT;
-   timeout = card->ext_csd.generic_cmd6_time;
-   card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-   } else {
-   notify_type = EXT_CSD_POWER_OFF_LONG;
-   timeout = card->ext_csd.power_off_longtime;
-   card->poweroff_notify_state = MMC_POWEROFF_LONG;
-   }
-
-   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_POWER_OFF_NOTIFICATION,
-   

Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-06-14 Thread Saugata Das
On 15 June 2012 00:36, Per Forlin  wrote:
> Hi Saugata,
>
> I can have a go and test it. But first I would like to bring up 3
> concerns that I have with this patch.
>
> 1. This patch should be sent to cc-stable in order to repair the bug
> introduced in 3.4

I shall sent it out today.

> 2. Is the bus_ops for poweroff_notify really necessary since only mmc
> use it?

This was recommended in the review from Ulf. If it is not adding to a
bug, I propose to keep it this way. Otherwise, we will be going in
circles :-)

> There are already bus_ops for suspend/resume,
> power_save/power_restore and remove. It feels like it would be
> possible to address poweroff_notify internally from mmc.c from theses
> bus_ops. I would be nice to add this feature without having to touch
> core.c.
>
> For instance. Call mmc_suspend() from mmc_remove()
> +++ b/drivers/mmc/core/mmc.c
> @@ -1302,7 +1302,7 @@ static void mmc_remove(struct mmc_host *host)
> +       __mmc_suspend(host, true);
>        mmc_remove_card(host->card);
>
> @@ -1347,7 +1347,7 @@ static void mmc_detect(struct mmc_host *host)
> -static int mmc_suspend(struct mmc_host *host)
> +static int __mmc_suspend(struct mmc_host *host, bool remove)
>
> @@ -1356,7 +1356,8 @@ static int mmc_suspend(struct mmc_host *host)
>        mmc_claim_host(host);
>        if (mmc_can_poweroff_notify(host->card) &&
> -               (host->caps2 & MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND)) {
> +               (host->caps2 & MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND ||
> +                remove)) {
>                err = mmc_poweroff_notify(host, MMC_PW_OFF_NOTIFY_SHORT);
>        } else {
>                if (mmc_card_can_sleep(host))
>
> @@ -1372,6 +1373,11 @@ static int mmc_suspend(struct mmc_host *host)
> +static int mmc_suspend(struct mmc_host *host)
> +{
> +       return __mmc_suspend(host, false);
> +}
> +
>
> Calling mmc_suspend from mmc_remove() has another advantage since it
> may issue SLEEP (CMD5) before the card is removed and power off. This
> is recommended by eMMC Vendors in order to shutdown the eMMC safely to
> prevent data corruption. When the platform shuts down the power to the
> eMMC will be turned off no matter what.

May be for MMC-4.41 cards this approach can be taken. For MMC-4.5, it
has to be power OFF notify when the power is removed. Lets do it for
another patch, since the intention of this patch is to fix the issues
around power OFF notify.

>
> 3. About the sleep and awake issue. This is not really related to
> poweroff_notify() as I see it. I would recommend to use CMD 0 to
> re-init the card safely after sleep in this patch. Then you could send
> out a sleep/awake patch that address this separately.  This would also
> make #1 easier, send patch to cc-stable. Adding save/restore IOS is a
> new feature and should not be sent to the cc-stable list. What do you
> think?

The problem in sending CMD0 without power OFF notify is possibility of
some data loss in MMC-4.5 devices.


>
> BR
> /Per
>
> On Thu, Jun 14, 2012 at 5:15 PM, Saugata Das  wrote:
>> On 14 June 2012 20:20, Ulf Hansson  wrote:
>>> Hi Girish,
>>>
>>> On 14 June 2012 15:21, Girish K S  wrote:
>>>> On 14 June 2012 18:43, Per Forlin  wrote:
>>>>> Hi Girish and Suagata,
>>>>>
>>>>> I have run some regression tests with this patch on our board (ux500
>>>>> family) running suspend and resume of the eMMC 4.41 device.
>>>>>
>>>>> The two patches I have looked at are:
>>>>> 1. "mmc: core: Fix PowerOff Notify suspend/resume" (merged)
>>>>> 2. " MMC-4.5 Power OFF Notify Rework"
>>>>>
>>>>> With only patch #1 the eMMC doesn't power up after in resume() after
>>>>> being suspended. The eMMC doesn't respond at all after suspend. It's
>>>>> not powered up.
>>>>> Running tests with #1 and #2, the card is powered up but it doesn't
>>>>> wake up after CMD5. Commands that arrive are after resume/CMD5
>>>>> timeouts. I even tried by increasing the awake timeout to 5 seconds
>>>>> but i didn't help.
>>>>>
>>>>> The eMMC on my board successfully suspends and resumes with patch #1
>>>>> and #2 if waking up the card using CMD0 (mmc_card_init()) instead of
>>>>> CMD5.
>>>>>
>>>>> Have anyone else seen the same issue?
>>>>> Have this patch been verified on a board together with eMMC 4.41 that
>>>>> supports card power off.
>>>> This rework patch is still under pro

Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-06-14 Thread Saugata Das
On 14 June 2012 20:20, Ulf Hansson  wrote:
> Hi Girish,
>
> On 14 June 2012 15:21, Girish K S  wrote:
>> On 14 June 2012 18:43, Per Forlin  wrote:
>>> Hi Girish and Suagata,
>>>
>>> I have run some regression tests with this patch on our board (ux500
>>> family) running suspend and resume of the eMMC 4.41 device.
>>>
>>> The two patches I have looked at are:
>>> 1. "mmc: core: Fix PowerOff Notify suspend/resume" (merged)
>>> 2. " MMC-4.5 Power OFF Notify Rework"
>>>
>>> With only patch #1 the eMMC doesn't power up after in resume() after
>>> being suspended. The eMMC doesn't respond at all after suspend. It's
>>> not powered up.
>>> Running tests with #1 and #2, the card is powered up but it doesn't
>>> wake up after CMD5. Commands that arrive are after resume/CMD5
>>> timeouts. I even tried by increasing the awake timeout to 5 seconds
>>> but i didn't help.
>>>
>>> The eMMC on my board successfully suspends and resumes with patch #1
>>> and #2 if waking up the card using CMD0 (mmc_card_init()) instead of
>>> CMD5.
>>>
>>> Have anyone else seen the same issue?
>>> Have this patch been verified on a board together with eMMC 4.41 that
>>> supports card power off.
>> This rework patch is still under progress. we are modifying it. In our
>> earlier discussions subhash has posted the
>> same issue and a solution for this.  we should save ios context before
>> sleep and restore ios before awake. soon rework patch will be
>> posted with the above recomenedded solution.
>>
>
> I think the best solution is to always do mmc_card_init when doing
> resume, it will be nice a simple.

Note that, with power OFF notify (MMC-4.5), there will be some pending
operation with the MMC controller. If we do mmc_card_init after
suspend, then there could be some data loss.

I  have passed to Per the latest patch (Subhash reported that it is
working). I shall forward to you as well. Lets solve the issue. If you
can work around, without mmc_card_init after suspend, then you are
most welcome to update the patch :-)


> Otherwise it will be somewhat tricky to keep track of what state we
> are in, and if the ios should be restored or not.
>
> Finally, I would be glad to help out in posting an updated version of
> this patch, if that OK with you?
>
> Kind regards
> Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] ext4: Context support

2012-06-12 Thread Saugata Das
On 12 June 2012 18:59, Arnd Bergmann  wrote:
> On Tuesday 12 June 2012, Saugata Das wrote:
>> On 11 June 2012 17:57, Ted Ts'o  wrote:
>> > On Mon, Jun 11, 2012 at 02:41:31PM +0300, Artem Bityutskiy wrote:
>> > The proof-of-concept patches seem to use the inode number as a way of
>> > trying to group related writes, but what about at a larger level than
>> > that?  For example, if we install a RPM or deb package where all of
>> > the files will likely be replaced together, should that be given the
>> > same context?
>>
>> In this patch, context is used at file level based on inode number.
>> So, in the above example, multiple contexts will be used for the
>> directory, file updates during RPM installation.
>>
>> >
>> > How likely does it have to be that related blocks written under the
>> > same context must be deleted at the same time for this concept to be
>> > helpful?
>>
>> There is no restriction that related blocks within the MMC context
>> needs to be deleted together
>
> I don't think that is correct. The most obvious implementation in eMMC
> hardware for this would be to group all data from one context to be
> written into the same erase block, in order to reduce the amount
> of garbage collection that needs to happen at erase time. AFAICT,
> the main interest here is, as Ted is guessing correctly, to make sure
> that all data which gets written into one context has roughly the
> same life time before it gets erased or overwritten.
>

The restriction is there on "large unit" context, which prevents
trim/erase of the blocks till the context is active. But we do not
enable "large unit". On non-"large unit" context, the specification
does not restrict the trim/erase of blocks based on context.


>> > If we have a context where it is the context assumption does
>> > not hold (example: a database where you have a random access
>> > read/write pattern with blocks updated in place) how harm will it be
>> > to the device format if those blocks are written under the same
>> > context?
>> >
>>
>> MMC context allows the data blocks to be overwritten or randomly accessed
>
> That is of course the defined behavior of a block device that does
> not change with the use of contexts. To get the best performance,
> a random-write database file would always reside in a context by itself
> and not get mixed with long-lived write-once data. If we have a way
> in the file system to tell whether a file is written linearly or randomly
> (e.g. by looking at the O_APPEND or O_CREAT flag), it might make sense
> to split the context space accordingly.
>
>> > The next set of questions we need to ask is how generalizable is this
>> > concept to devices that might be more sophisticated than simple eMMC
>> > devices.  If we're going to expose something all the way out to the
>> > file system layer, it would be nice if it worked on more than just
>> > low-end flash devices, but also on more sophisticated devices as well.
>> >
>>
>> This context mechanism will be used on both UFS and MMC devices. If
>> there are some alternate suggestions on what can be used as context
>> from file system perspective, then please  suggest.
>
> One suggestion that has been made before was to base the context on
> the process ID rather than the inode number, but that has many other
> problems, e.g. when the same file gets written by multiple processes.
>
>        Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] ext4: Context support

2012-06-12 Thread Saugata Das
On 11 June 2012 17:57, Ted Ts'o  wrote:
> On Mon, Jun 11, 2012 at 02:41:31PM +0300, Artem Bityutskiy wrote:
>>
>> Word "context" is very generic and it is widely used various things, and
>> I believe we should try to avoid overloading this term and obfuscating
>> the I/O stack with various functions and other identifiers like
>> "get_context()". This would hurt readability. It is fine to use it
>> withing the UFS-specific code, but not globally withing the kernel code.
>>
>> I do not really have good name candidates, but even "ufscontext" is
>> already better than just "context". Or "iocontext" ? Or just "ufsdata" ?
>
> Before we try naming it, can we get some more details about exactly
> how context in the eMMC context works?
>
> It appears to be a way of grouping related writes together (yes?) but
> at what granularity?  What are the restrictions at the device level?
>

Yes, the idea is to group the read, write requests for a file to a
common context so that MMC can optimize the performance.

There is no restriction on the number of blocks which can be added in
the context. However, MMC restricts the number of contexts to 15. So,
potentially, multiple file system contexts will map to single MMC
context.

> The proof-of-concept patches seem to use the inode number as a way of
> trying to group related writes, but what about at a larger level than
> that?  For example, if we install a RPM or deb package where all of
> the files will likely be replaced together, should that be given the
> same context?

In this patch, context is used at file level based on inode number.
So, in the above example, multiple contexts will be used for the
directory, file updates during RPM installation.

>
> How likely does it have to be that related blocks written under the
> same context must be deleted at the same time for this concept to be
> helpful?

There is no restriction that related blocks within the MMC context
needs to be deleted together

> If we have a context where it is the context assumption does
> not hold (example: a database where you have a random access
> read/write pattern with blocks updated in place) how harm will it be
> to the device format if those blocks are written under the same
> context?
>

MMC context allows the data blocks to be overwritten or randomly accessed

> The next set of questions we need to ask is how generalizable is this
> concept to devices that might be more sophisticated than simple eMMC
> devices.  If we're going to expose something all the way out to the
> file system layer, it would be nice if it worked on more than just
> low-end flash devices, but also on more sophisticated devices as well.
>

This context mechanism will be used on both UFS and MMC devices. If
there are some alternate suggestions on what can be used as context
from file system perspective, then please  suggest.


> Regards,
>
>                                        - Ted
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] block: Context support

2012-06-11 Thread Saugata Das
From: Saugata Das 

On eMMC and UFS devices there is a new feature of setting context with each
read or write. The idea is to classify the data from different files and
apply the realibility on the complete file instead of individual writes,
which helps in performance. A new address space operation has been a added
to get the context from file system and set up the bi_context field in bio.
Then we need to ensure that bio from different contexts are not merged. The
context is then passed to the underlying driver as part of the read or write
request. Since the number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC context.

Signed-off-by: Saugata Das 
---
 block/blk-core.c|1 +
 block/blk-merge.c   |3 +++
 fs/mpage.c  |   12 
 include/linux/blk_types.h   |1 +
 include/linux/blkdev.h  |1 +
 include/linux/buffer_head.h |2 ++
 include/linux/fs.h  |1 +
 7 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 1f61b74..274e05d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1309,6 +1309,7 @@ void init_request_from_bio(struct request *req, struct 
bio *bio)
req->errors = 0;
req->__sector = bio->bi_sector;
req->ioprio = bio_prio(bio);
+   req->context = bio->bi_context;
blk_rq_bio_prep(req->q, req, bio);
 }
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 160035f..ed70d56 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -497,6 +497,9 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
if (bio_integrity(bio) != blk_integrity_rq(rq))
return false;
 
+   if (bio->bi_context != rq->bio->bi_context)
+   return false;
+
return true;
 }
 
diff --git a/fs/mpage.c b/fs/mpage.c
index 0face1c..4889842 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -293,6 +293,12 @@ alloc_new:
goto confused;
}
 
+   if (page && page->mapping && page->mapping->a_ops &&
+   page->mapping->a_ops->get_context)
+   bio->bi_context = page->mapping->a_ops->get_context(page);
+   else
+   bio->bi_context = 0;
+
length = first_hole << blkbits;
if (bio_add_page(bio, page, length, 0) < length) {
bio = mpage_bio_submit(READ, bio);
@@ -581,6 +587,12 @@ alloc_new:
goto confused;
}
 
+   if (page && page->mapping && page->mapping->a_ops &&
+   page->mapping->a_ops->get_context)
+   bio->bi_context = page->mapping->a_ops->get_context(page);
+   else
+   bio->bi_context = 0;
+
/*
 * Must try to add the page before marking the buffer clean or
 * the confused fail path above (OOM) will be very confused when
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 4053cbd..f3ac448 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -42,6 +42,7 @@ struct bio {
 
unsigned short  bi_vcnt;/* how many bio_vec's */
unsigned short  bi_idx; /* current index into bvl_vec */
+   unsigned long   bi_context; /* context of this bio */
 
/* Number of segments in this BIO after
 * physical address coalescing is performed.
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2aa2466..0dd9a08 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -167,6 +167,7 @@ struct request {
struct list_head timeout_list;
unsigned int timeout;
int retries;
+   unsigned long context;  /* context of this request */
 
/*
 * completion callback.
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 13bba17..0776564 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -72,6 +72,8 @@ struct buffer_head {
struct list_head b_assoc_buffers; /* associated with another mapping */
struct address_space *b_assoc_map;  /* mapping this buffer is
   associated with */
+   unsigned long   b_context; /* context for this buffer within the
+   storage device */
atomic_t b_count;   /* users using this buffer_head */
 };
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8de6755..4b379d8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -626,6 +626,7 @@ struct address_space_operations {
int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
unsigned long);
int (*error_remove_page)(struct address_space *, struct pag

[PATCH 3/3] mmc: Context support

2012-06-11 Thread Saugata Das
From: Saugata Das 

This patch implements the context ID support at MMC layer. From file system
(ext4), the context is passed in the request structure. At MMC layer the
context is retrieved from the request structure and then used in the CMD23
argument. Since number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC contexts. When the REQ_SYNC or REQ_FLUSH
flag is set, the context is flushed or sync'ed, in which the context is
closed so that the data blocks are safely written out to non-volatile memory
and then the context is opened again.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |   37 ++-
 drivers/mmc/core/core.c  |   61 ++
 drivers/mmc/core/mmc.c   |   25 +++
 include/linux/mmc/card.h |6 
 include/linux/mmc/core.h |4 +++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |2 +
 7 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dabec55..4760d5a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -958,6 +958,15 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, 
struct request *req)
struct mmc_card *card = md->queue.card;
int ret = 0;
 
+   /*
+* The flush command is a synchronization point from file system.
+* The contexts are flushed here to ensure that the data written
+* in the open contexts are saved reliably in non-volatile media
+*/
+   ret = mmc_flush_contexts(card);
+   if (ret)
+   ret = -EIO;
+
ret = mmc_flush_cache(card);
if (ret)
ret = -EIO;
@@ -1207,11 +1216,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
 */
if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
(do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
-do_data_tag)) {
+do_data_tag || (card->ext_csd.max_context_id > 0))) {
+   int context_id = (req->context &&
+   card->ext_csd.max_context_id) ?
+   (req->context % card->ext_csd.max_context_id + 1) :
+   0;
brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
brq->sbc.arg = brq->data.blocks |
(do_rel_wr ? (1 << 31) : 0) |
-   (do_data_tag ? (1 << 29) : 0);
+   (do_data_tag ? (1 << 29) : 0) |
+   (!do_data_tag ? (context_id << 25) : 0);
brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
brq->mrq.sbc = &brq->sbc;
}
@@ -1440,6 +1454,25 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct 
request *req)
mmc_blk_issue_rw_rq(mq, NULL);
ret = mmc_blk_issue_flush(mq, req);
} else {
+   if (req && (req->cmd_flags & REQ_SYNC) &&
+   req->context && card->ext_csd.max_context_id) {
+   int context_cfg_id =
+   req->context % card->ext_csd.max_context_id;
+   /*
+* The SYNC command is a synchronization point from
+* file system. The relevent context is sync'ed here
+* to ensure that the data written in the open context
+* are saved reliably in non-volatile media
+*/
+   if (card->host->areq)
+   mmc_blk_issue_rw_rq(mq, NULL);
+   mmc_sync_context(card, context_cfg_id);
+   /*
+* This write will go without context to ensure
+* that it is reliably written
+*/
+   req->context = 0;
+   }
ret = mmc_blk_issue_rw_rq(mq, req);
}
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ba821fe..54857f9 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2262,6 +2262,67 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 }
 EXPORT_SYMBOL(mmc_cache_ctrl);
 
+static inline int mmc_set_context_conf(struct mmc_card *card,
+   int context_cfg_id, int context_act_dir)
+{
+   return mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CONTEXT_CONF + context_cfg_id,
+   context_act_dir, card->ext_csd.generic_cmd6_time);
+}
+
+/*
+ * Synchronize a context by first closing the context and then
+ * opening it
+ */
+int mmc_sync_context(struct mmc_card *card, int context_cfg_id)
+{
+   int err = 0;
+
+ 

[PATCH 2/3] ext4: Context support

2012-06-11 Thread Saugata Das
From: Saugata Das 

On eMMC and UFS devices there is a new feature of setting context with
each read or write. The idea is to classify the data from different files
and apply the realibility on the complete file instead of individual writes.
On ext4 file system, the inode number of the file is passed as b_context
in the bh structure during write and via the get_context callback function
during read. Since number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC context.

Signed-off-by: Saugata Das 
---
 fs/ext4/inode.c   |   33 +
 fs/ext4/page-io.c |1 +
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 754fe77..2667396 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -790,6 +790,21 @@ static int do_journal_get_write_access(handle_t *handle,
return ret;
 }
 
+/* Get the context of the buffer within the underlying storage device */
+static int ext4_get_context(struct page *page)
+{
+   if (page && page->mapping && page->mapping->host)
+   return page->mapping->host->i_ino;
+   else
+   return 0;
+}
+
+static int ext4_set_buffer_context(handle_t *handle, struct buffer_head *bh)
+{
+   bh->b_context = ext4_get_context(bh->b_page);
+   return 0;
+}
+
 static int ext4_get_block_write(struct inode *inode, sector_t iblock,
   struct buffer_head *bh_result, int create);
 static int ext4_write_begin(struct file *file, struct address_space *mapping,
@@ -843,6 +858,11 @@ retry:
from, to, NULL, do_journal_get_write_access);
}
 
+   if (!ret && walk_page_buffers(NULL, page_buffers(page),
+   from, to, NULL, ext4_set_buffer_context)) {
+   ext4_warning(inode->i_sb, "Couldn't set context\n");
+   }
+
if (ret) {
unlock_page(page);
page_cache_release(page);
@@ -2394,8 +2414,11 @@ static int ext4_da_write_begin(struct file *file, struct 
address_space *mapping,
pgoff_t index;
struct inode *inode = mapping->host;
handle_t *handle;
+   unsigned from, to;
 
index = pos >> PAGE_CACHE_SHIFT;
+   from = pos & (PAGE_CACHE_SIZE - 1);
+   to = from + len;
 
if (ext4_nonda_switch(inode->i_sb)) {
*fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
@@ -2444,6 +2467,12 @@ retry:
 
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
+
+   if (walk_page_buffers(NULL, page_buffers(page),
+   from, to, NULL, ext4_set_buffer_context)) {
+   ext4_warning(inode->i_sb, "Couldn't set context\n");
+   }
+
 out:
return ret;
 }
@@ -3040,6 +3069,7 @@ static const struct address_space_operations 
ext4_ordered_aops = {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_writeback_aops = {
@@ -3055,6 +3085,7 @@ static const struct address_space_operations 
ext4_writeback_aops = {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_journalled_aops = {
@@ -3070,6 +3101,7 @@ static const struct address_space_operations 
ext4_journalled_aops = {
.direct_IO  = ext4_direct_IO,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_da_aops = {
@@ -3086,6 +3118,7 @@ static const struct address_space_operations ext4_da_aops 
= {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 void ext4_set_aops(struct inode *inode)
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index dcdeef1..bf1381e 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -296,6 +296,7 @@ static int io_submit_init(struct ext4_io_submit *io,
bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
bio->bi_bdev = bh->b_bdev;
+   bio->bi_context = bh->b_context;
bio->bi_private = io->io_end = io_end;
bio->bi_end_io = ext4_end_bio;
 
--

Re: [PATCH v5] MMC-4.5 Power OFF Notify Rework

2012-05-28 Thread Saugata Das
On 28 May 2012 16:33, Subhash Jadavani  wrote:
> Hi Girish, Saugata,
>
> There is an issue with this patch during resume. Please find comments inline
> below:
>
>> -Original Message-
>> From: Girish K S [mailto:girish.shivananja...@linaro.org]
>> Sent: Tuesday, May 22, 2012 5:15 PM
>> To: linux-mmc@vger.kernel.org
>> Cc: c...@laptop.org; patc...@linaro.org; ulf.hans...@stericsson.com;
>> saugata@linaro.org; subha...@codeaurora.org; Girish K S
>> Subject: [PATCH v5] MMC-4.5 Power OFF Notify Rework
>>
>> From: Saugata Das 
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host controller drivers will set this CAP, if they switch off both Vcc and
> Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that
>> there is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched
>> off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE,
>> mmc_stop_host), which does reinitialization of the eMMC on the return path
> of
>> the power management routines (e.g. mmc_power_restore_host,
>> mmc_pm_notify/PM_POST_RESTORE, mmc_start_host).
>>
>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>> from the suspend sequence. If it is sent from shutdown sequence then it is
> set
>> to POWER_OFF_LONG.
>>
>> Earlier implementation of PowerOff Notify as a core function is replaced
> as a
>> device's bus operation.
>>
>> Signed-off-by: Saugata Das 
>> Signed-off-by: Girish K S 
>>
>> changes in v5:
>>       modified the the handling of return value in mmc_poweroff_notify.
>> changes in v4:
>>       As suggested in review,
>>       - Moved mmc_can_poweroff_notify to core.c
>>       - Moved mmc_claim_host, mmc_release_host outside
>> mmc_poweroff_notify
>>       - Added check for wrong initialization for poweroff_notify_type
>>       - mmc_poweroff_notify is modified to take as 2nd parameter changes
>> in v3:
>>       This version addresses the review comments given by Subhash and Ulf
>> changes in v2:
>>       This version addresses the changes suggested by Ulf
>> ---
>>  drivers/mmc/core/core.c   |  108
> ++--
>>  drivers/mmc/core/core.h   |    1 +
>>  drivers/mmc/core/mmc.c    |   56 ---
>>  drivers/mmc/host/dw_mmc.c |    5 --
>>  drivers/mmc/host/sdhci.c  |    9 
>>  include/linux/mmc/card.h  |    5 +-
>>  include/linux/mmc/core.h  |    1 +
>>  include/linux/mmc/host.h  |    5 +--
>>  include/linux/mmc/mmc.h   |    7 +++
>>  9 files changed, 104 insertions(+), 93 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index
>> 0b6141d..fe616b9 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1101,48 +1101,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>       mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host) -{
>> -     struct mmc_card *card;
>> -     unsigned int timeout;
>> -     unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -     int err = 0;
>> -
>> -     card = host->card;
>> -     mmc_claim_host(host);
>> -
>> -     /*
>> -      * Send power notify command only if card
>> -      * is mmc and notify state is powered ON
>> -      */
>> -     if (card && mmc_card_mmc(card) &&
>> -         (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -             if (host->power_notify_type ==
>> MMC_HOST_PW_NOTIFY_SHORT) {
>> -                     notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                     timeout = card->ext_csd.generic_cmd6_time;
>> -                     card->poweroff_notify_state =
>> MMC_POWEROFF_SHORT;
>> -             } else {
>> -                     notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                     time

Re: [RFC 3/3] mmc: Context support

2012-05-18 Thread Saugata Das
On 18 May 2012 18:56, Subhash Jadavani  wrote:
> Hi Sougata,
>
> Please find few comments inline below.
>

Many thanks for your time and comments,


> Regards,
> Subhash
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> ow...@vger.kernel.org] On Behalf Of Saugata Das
>> Sent: Wednesday, May 16, 2012 9:01 PM
>> To: linux-e...@vger.kernel.org; linux-fsde...@vger.kernel.org; linux-
>> m...@vger.kernel.org
>> Cc: arnd.bergm...@linaro.org; ven...@linaro.org; saugata@linaro.org
>> Subject: [RFC 3/3] mmc: Context support
>>
>> From: Saugata Das 
>>
>> This patch implements the context ID support at MMC layer. From file
>> system (ext4), the context is passed in the request structure. At MMC
> layer
>> the context is retrieved from the request structure and then used in the
>> CMD23 argument. Since number of MMC contexts is limited, multiple file
>> system contexts are mapped to single MMC contexts. When the REQ_SYNC
>> or REQ_FLUSH flag is set, the context is flushed or sync'ed, in which the
>> context is closed so that the data blocks are safely written out to non-
>> volatile memory and then the context is opened again.
>>
>> Signed-off-by: Saugata Das 
>> ---
>>  drivers/mmc/card/block.c |   35 +-
>>  drivers/mmc/core/core.c  |   72
>> ++
>>  drivers/mmc/core/mmc.c   |   28 ++
>>  include/linux/mmc/card.h |    4 ++
>>  include/linux/mmc/core.h |    4 ++
>>  include/linux/mmc/host.h |    1 +
>>  include/linux/mmc/mmc.h  |    3 ++
>>  7 files changed, 145 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index
>> dabec55..914f942 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -958,6 +958,15 @@ static int mmc_blk_issue_flush(struct mmc_queue
>> *mq, struct request *req)
>>       struct mmc_card *card = md->queue.card;
>>       int ret = 0;
>>
>> +     /*
>> +      * The flush command is a synchronization point from file system.
>> +      * The contexts are flushed here to ensure that the data written
>> +      * in the open contexts are saved reliably in non-volatile media
>> +      */
>> +     ret = mmc_flush_contexts(card);
>
> This is called unconditionally. Shouldn't we check if context is really
> enabled or not and host have asked (by defining MMC_CAP2_CONTEXT) for it or
> not.

I think the best approach will be to set max_context_id to 0 in
mmc_read_ext_csd, if MMC_CAP2_CONTEXT is not enabled. Then, we do not
have to add a check for MMC_CAP2_CONTEXT, wherever we want to use the
context.

>
> Also shouln't this mmc_flush_contexts() be called after the
> __blk_end_request_all() in this same function?
>

I do not think so. This is in line with how mmc_flush_cache is done
today, i.e. we complete the closing/flushing all pending operations on
the device before  __blk_end_request_all.


>> +     if (ret)
>> +             ret = -EIO;
>> +
>>       ret = mmc_flush_cache(card);
>>       if (ret)
>>               ret = -EIO;
>> @@ -1207,11 +1216,16 @@ static void mmc_blk_rw_rq_prep(struct
>> mmc_queue_req *mqrq,
>>        */
>>       if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq-
>> >cmd.opcode) &&
>>           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
>> -          do_data_tag)) {
>> +          do_data_tag || (card->ext_csd.max_context_id > 0))) {
>
> card->ext_csd.max_context_id can be non-zero even if host has not enabled
> MMC_CAP2_CONTEXT cap.  So you should add proper check here before tagging
> the context id.
>

I will set max_context_id to 0 in mmc_read_ext_csd if MMC_CAP2_CONTEXT
is not set as mentioned above.

>> +             int context_id = (req->context &&
>> +                     card->ext_csd.max_context_id) ?
>> +                     (req->context % card->ext_csd.max_context_id + 1) :
>> +                     0;
>>               brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
>>               brq->sbc.arg = brq->data.blocks |
>>                       (do_rel_wr ? (1 << 31) : 0) |
>> -                     (do_data_tag ? (1 << 29) : 0);
>> +                     (do_data_tag ? (1 << 29) : 0) |
>> +                     (!do_data_tag ? (context_id << 25) : 0);
>>               brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
>>               brq->mrq.sbc = &brq->sbc;

Re: [PATCH v3] MMC-4.5 Power OFF Notify Rework

2012-05-18 Thread Saugata Das
On 18 May 2012 16:29, Subhash Jadavani  wrote:
> On 5/18/2012 3:16 PM, Girish K S wrote:
>>
>> From: Saugata Das
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>> which
>> does reinitialization of the eMMC on the return path of the power
>> management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>> from
>> the suspend sequence. If it is sent from shutdown sequence then it is set
>> to
>> POWER_OFF_LONG.
>>
>> Previuos implementation of PowerOff Notify as a core function is replaced
>> as
>
>
> s/perviuos/previous
>
>> a device's bus operation.
>>
>> Signed-off-by: Saugata Das
>> Signed-off-by: Girish K S
>>
>> changes in v4:
>>        As suggested in review,
>>        - Moved mmc_can_poweroff_notify to core.c
>>        - Moved mmc_claim_host, mmc_release_host outside
>> mmc_poweroff_notify
>>        - Added check for wrong initialization for poweroff_notify_type
>>        - mmc_poweroff_notify is modified to take as 2nd parameter
>> changes in v3:
>>        This version addresses the review comments given by Subhash and Ulf
>> changes in v2:
>>        This version addresses the changes suggested by Ulf
>> ---
>>  drivers/mmc/core/core.c   |  106
>> ++---
>>  drivers/mmc/core/core.h   |    1 +
>>  drivers/mmc/core/mmc.c    |   56 ---
>>  drivers/mmc/host/dw_mmc.c |    5 --
>>  drivers/mmc/host/sdhci.c  |    9 
>>  include/linux/mmc/card.h  |    5 +-
>>  include/linux/mmc/core.h  |    1 +
>>  include/linux/mmc/host.h  |    5 +--
>>  include/linux/mmc/mmc.h   |    7 +++
>>  9 files changed, 102 insertions(+), 93 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index 0b6141d..3011122 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1101,48 +1101,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>        mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> -{
>> -       struct mmc_card *card;
>> -       unsigned int timeout;
>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> -
>> -       card = host->card;
>> -       mmc_claim_host(host);
>> -
>> -       /*
>> -        * Send power notify command only if card
>> -        * is mmc and notify state is powered ON
>> -        */
>> -       if (card&&  mmc_card_mmc(card)&&
>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                       timeout = card->ext_csd.generic_cmd6_time;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>> -               } else {
>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                       timeout = card->ext_csd.power_off_longtime;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>> -               }
>> -
>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                                notify_type, timeout);
>> -
>> -               if (err&&  err != -EBADMSG)
>>
>> -                 

Re: [PATCH v2 1/2] [MMC-4.5] Disable emulation

2012-05-17 Thread Saugata Das
On 17 May 2012 17:13, Subhash Jadavani  wrote:
> Looks good to me.
> Reviewed-by: Subhash Jadavani 
>

Thanks Subhash, Namjae Jeon.

Chris, will you please merge this patch for your next release.


> Regards,
> Subhash
>
>> -Original Message-----
>> From: Saugata Das [mailto:saugata@stericsson.com]
>> Sent: Thursday, May 17, 2012 4:32 PM
>> To: linux-mmc@vger.kernel.org
>> Cc: patc...@linaro.org; saugata@linaro.org; subha...@codeaurora.org;
>> arnd.bergm...@linaro.org; ven...@linaro.org; lpor...@micron.com;
>> linkinj...@gmail.com
>> Subject: [PATCH v2 1/2] [MMC-4.5] Disable emulation
>>
>> From: Saugata Das 
>>
>> This patch adds the support for large sector size of 4KB by disabling
>> emulation.
>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>> mmc_blk_alloc_req.
>>
>> In order to use this patch for 4KB sector size, ensure that
>> USE_NATIVE_SECTOR is enabled, partition table is 4KB sector size aligned
> and
>> file system block and sector size are 4KB multiples.
>>
>> Signed-off-by: Saugata Das 
>>
>> changes in v2:
>>       Updated description, added pr_err based on review feedback
>> ---
>>  drivers/mmc/card/block.c |   18 --
>>  drivers/mmc/core/mmc.c   |    2 ++
>>  2 files changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index
>> 91cda75..d628c5d 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>> *mq, struct request *rqc)
>>       int ret = 1, disable_multi = 0, retry = 0, type;
>>       enum mmc_blk_status status;
>>       struct mmc_queue_req *mq_rq;
>> -     struct request *req;
>> +     struct request *req = rqc;
>>       struct mmc_async_req *areq;
>>
>>       if (!rqc && !mq->mqrq_prev->req)
>> @@ -1292,6 +1292,16 @@ static int mmc_blk_issue_rw_rq(struct
>> mmc_queue *mq, struct request *rqc)
>>
>>       do {
>>               if (rqc) {
>> +                     /*
>> +                      * When 4KB native sector is enabled, only 8 blocks
>> +                      * multiple read or write is allowed
>> +                      */
>> +                     if ((brq->data.blocks & 0x07) &&
>> +                             (card->ext_csd.data_sector_size == 4096)) {
>> +                             pr_err("%s: Transfer size is not 4KB sector
>> size aligned\n",
>> +                                     req->rq_disk->disk_name);
>> +                             goto cmd_abort;
>> +                     }
>>                       mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
>>                       areq = &mq->mqrq_cur->mmc_active;
>>               } else
>> @@ -1539,7 +1549,11 @@ static struct mmc_blk_data
>> *mmc_blk_alloc_req(struct mmc_card *card,
>>       snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>                "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>
>> -     blk_queue_logical_block_size(md->queue.queue, 512);
>> +     if (mmc_card_mmc(card))
>> +             blk_queue_logical_block_size(md->queue.queue,
>> +                     card->ext_csd.data_sector_size);
>> +     else
>> +             blk_queue_logical_block_size(md->queue.queue, 512);
>>       set_capacity(md->disk, size);
>>
>>       if (mmc_host_cmd23(card->host)) {
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index
>> 7268c26..11444c6 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -516,6 +516,8 @@ static int mmc_read_ext_csd(struct mmc_card *card,
>> u8 *ext_csd)
>>               } else {
>>                       card->ext_csd.data_tag_unit_size = 0;
>>               }
>> +     } else {
>> +             card->ext_csd.data_sector_size = 512;
>>       }
>>
>>  out:
>> --
>> 1.7.4.3
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-17 Thread Saugata Das
On 17 May 2012 13:18, Subhash Jadavani  wrote:
> Reviewed-by: Subhash Jadavani 
>
> Sougata,
> There are additional blank lines before and after the
> do_disable_512B_emulation() function. You may want to remove them.

I have done that in the new version. Please check.


>
> Regards,
> Subhash
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> ow...@vger.kernel.org] On Behalf Of Saugata Das
>> Sent: Wednesday, May 16, 2012 9:57 PM
>> To: linux-mmc@vger.kernel.org; ven...@linaro.org
>> Cc: patc...@linaro.org; saugata@linaro.org; arnd.bergm...@linaro.org;
>> lpor...@micron.com
>> Subject: [PATCH 2/2] [MMC-4.5] [MMC UTIL] Disable emulation
>>
>> From: Saugata Das 
>>
>> In this patch, we add utility to disable emulation mode in the eMMC-4.5.
>> This is done to increase the data sector size to 4KB.
>>
>> Signed-off-by: Saugata Das 
>>
>> changes in v2:
>>       Review rework based on comments from Subhash
>> ---
>>  mmc.c      |    6 ++
>>  mmc.h      |   10 ++
>>  mmc_cmds.c |   51
>> +++
>>  mmc_cmds.h |    1 +
>>  4 files changed, 68 insertions(+), 0 deletions(-)
>>
>> diff --git a/mmc.c b/mmc.c
>> index c27fc24..ebc7ab2 100644
>> --- a/mmc.c
>> +++ b/mmc.c
>> @@ -65,6 +65,12 @@ static struct Command commands[] = {
>>               "Set the eMMC writeprotect status of .",
>>         NULL
>>       },
>> +     { do_disable_512B_emulation, -1,
>> +       "disable 512B emulation", "\n"
>> +             "Set the eMMC data sector size to 4KB by disabling emulation
>> .",
>> +       NULL
>> +     },
>> +
>>       { 0, 0, 0, 0 }
>>  };
>>
>> diff --git a/mmc.h b/mmc.h
>> index 3af36f1..34c31d3 100644
>> --- a/mmc.h
>> +++ b/mmc.h
>> @@ -35,6 +35,16 @@
>>  #define EXT_CSD_PART_SWITCH_TIME     199
>>  #define EXT_CSD_BOOT_CFG             179
>>  #define EXT_CSD_BOOT_WP                      173
>> +#define EXT_CSD_WR_REL_PARAM 166
>> +#define EXT_CSD_NATIVE_SECTOR_SIZE   63 /* R */
>> +#define EXT_CSD_USE_NATIVE_SECTOR    62 /* R/W */
>> +#define EXT_CSD_DATA_SECTOR_SIZE     61 /* R */
>> +
>> +/*
>> + * WR_REL_PARAM field definitions
>> + */
>> +#define HS_CTRL_REL  (1<<0)
>> +#define EN_REL_WR    (1<<2)
>>
>>  /*
>>   * EXT_CSD field definitions
>> diff --git a/mmc_cmds.c b/mmc_cmds.c
>> index 4562cef..f0e64c9 100644
>> --- a/mmc_cmds.c
>> +++ b/mmc_cmds.c
>> @@ -168,6 +168,57 @@ int do_writeprotect_set(int nargs, char **argv)
>>       return ret;
>>  }
>>
>> +
>> +int do_disable_512B_emulation(int nargs, char **argv) {
>> +     __u8 ext_csd[512], native_sector_size, data_sector_size,
>> wr_rel_param;
>> +     int fd, ret;
>> +     char *device;
>> +
>> +     CHECK(nargs != 2, "Usage: mmc \n", exit(1));
>> +
>> +     device = argv[1];
>> +
>> +     fd = open(device, O_RDWR);
>> +     if (fd < 0) {
>> +             perror("open");
>> +             exit(1);
>> +     }
>> +
>> +     ret = read_extcsd(fd, ext_csd);
>> +     if (ret) {
>> +             fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
>> +             exit(1);
>> +     }
>> +
>> +     wr_rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
>> +     native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
>> +     data_sector_size = ext_csd[EXT_CSD_DATA_SECTOR_SIZE];
>> +
>> +     if (native_sector_size &&
>> +             !data_sector_size &&
>> +             (wr_rel_param & EN_REL_WR)) {
>> +             ret = write_extcsd_value(fd,
>> EXT_CSD_USE_NATIVE_SECTOR, 1);
>> +
>> +             if (ret) {
>> +                     fprintf(stderr, "Could not write 0x%02x to "
>> +                                     "EXT_CSD[%d] in %s\n",
>> +                                     1, EXT_CSD_BOOT_WP, device);
>> +                     exit(1);
>> +             }
>> +             printf("MMC disable 512B emulation successful\n"
>> +                             "Now reset the device to switch to 4KB "
>> +                             "native sector mode\n");
>> +     } else if (native_sector_size && data_sector_size) {
>> +             printf("MMC already disabled 512

[PATCH v2 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-17 Thread Saugata Das
From: Saugata Das 

In this patch, we add utility to disable emulation mode in the eMMC-4.5.
This is done to increase the data sector size to 4KB.

Signed-off-by: Saugata Das 

changes in v2:
Removed extra blank lines around do_disable_512B_emulation
Review rework based on comments from Subhash
---
 mmc.c  |6 ++
 mmc.h  |   10 ++
 mmc_cmds.c |   49 +
 mmc_cmds.h |1 +
 4 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/mmc.c b/mmc.c
index c27fc24..ebc7ab2 100644
--- a/mmc.c
+++ b/mmc.c
@@ -65,6 +65,12 @@ static struct Command commands[] = {
"Set the eMMC writeprotect status of .",
  NULL
},
+   { do_disable_512B_emulation, -1,
+ "disable 512B emulation", "\n"
+   "Set the eMMC data sector size to 4KB by disabling emulation 
.",
+ NULL
+   },
+
{ 0, 0, 0, 0 }
 };
 
diff --git a/mmc.h b/mmc.h
index 3af36f1..34c31d3 100644
--- a/mmc.h
+++ b/mmc.h
@@ -35,6 +35,16 @@
 #define EXT_CSD_PART_SWITCH_TIME   199
 #define EXT_CSD_BOOT_CFG   179
 #define EXT_CSD_BOOT_WP173
+#define EXT_CSD_WR_REL_PARAM   166
+#define EXT_CSD_NATIVE_SECTOR_SIZE 63 /* R */
+#define EXT_CSD_USE_NATIVE_SECTOR  62 /* R/W */
+#define EXT_CSD_DATA_SECTOR_SIZE   61 /* R */
+
+/*
+ * WR_REL_PARAM field definitions
+ */
+#define HS_CTRL_REL(1<<0)
+#define EN_REL_WR  (1<<2)
 
 /*
  * EXT_CSD field definitions
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 4562cef..4bc1fd6 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -168,6 +168,55 @@ int do_writeprotect_set(int nargs, char **argv)
return ret;
 }
 
+int do_disable_512B_emulation(int nargs, char **argv)
+{
+   __u8 ext_csd[512], native_sector_size, data_sector_size, wr_rel_param;
+   int fd, ret;
+   char *device;
+
+   CHECK(nargs != 2, "Usage: mmc \n", exit(1));
+
+   device = argv[1];
+
+   fd = open(device, O_RDWR);
+   if (fd < 0) {
+   perror("open");
+   exit(1);
+   }
+
+   ret = read_extcsd(fd, ext_csd);
+   if (ret) {
+   fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+   exit(1);
+   }
+
+   wr_rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+   native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
+   data_sector_size = ext_csd[EXT_CSD_DATA_SECTOR_SIZE];
+
+   if (native_sector_size &&
+   !data_sector_size &&
+   (wr_rel_param & EN_REL_WR)) {
+   ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1);
+
+   if (ret) {
+   fprintf(stderr, "Could not write 0x%02x to "
+   "EXT_CSD[%d] in %s\n",
+   1, EXT_CSD_BOOT_WP, device);
+   exit(1);
+   }
+   printf("MMC disable 512B emulation successful\n"
+   "Now reset the device to switch to 4KB "
+   "native sector mode\n");
+   } else if (native_sector_size && data_sector_size) {
+   printf("MMC already disabled 512B emulation mode\n");
+   } else {
+   printf("MMC does not support disabling 512B emulation mode\n");
+   }
+
+   return ret;
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
__u8 ext_csd[512], ext_csd_rev, reg;
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 66e9acb..56f46d7 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv);
 int do_write_extcsd(int nargs, char **argv);
 int do_writeprotect_get(int nargs, char **argv);
 int do_writeprotect_set(int nargs, char **argv);
+int do_disable_512B_emulation(int nargs, char **argv);
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] [MMC-4.5] Disable emulation

2012-05-17 Thread Saugata Das
From: Saugata Das 

This patch adds the support for large sector size of 4KB by disabling emulation.
This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
mmc_blk_alloc_req.

In order to use this patch for 4KB sector size, ensure that USE_NATIVE_SECTOR
is enabled, partition table is 4KB sector size aligned and file system block
and sector size are 4KB multiples.

Signed-off-by: Saugata Das 

changes in v2:
Updated description, added pr_err based on review feedback
---
 drivers/mmc/card/block.c |   18 --
 drivers/mmc/core/mmc.c   |2 ++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 91cda75..d628c5d 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
int ret = 1, disable_multi = 0, retry = 0, type;
enum mmc_blk_status status;
struct mmc_queue_req *mq_rq;
-   struct request *req;
+   struct request *req = rqc;
struct mmc_async_req *areq;
 
if (!rqc && !mq->mqrq_prev->req)
@@ -1292,6 +1292,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
 
do {
if (rqc) {
+   /*
+* When 4KB native sector is enabled, only 8 blocks
+* multiple read or write is allowed
+*/
+   if ((brq->data.blocks & 0x07) &&
+   (card->ext_csd.data_sector_size == 4096)) {
+   pr_err("%s: Transfer size is not 4KB sector 
size aligned\n",
+   req->rq_disk->disk_name);
+   goto cmd_abort;
+   }
mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
areq = &mq->mqrq_cur->mmc_active;
} else
@@ -1539,7 +1549,11 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
 "mmcblk%d%s", md->name_idx, subname ? subname : "");
 
-   blk_queue_logical_block_size(md->queue.queue, 512);
+   if (mmc_card_mmc(card))
+   blk_queue_logical_block_size(md->queue.queue,
+   card->ext_csd.data_sector_size);
+   else
+   blk_queue_logical_block_size(md->queue.queue, 512);
set_capacity(md->disk, size);
 
if (mmc_host_cmd23(card->host)) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7268c26..11444c6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -516,6 +516,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
} else {
card->ext_csd.data_tag_unit_size = 0;
}
+   } else {
+   card->ext_csd.data_sector_size = 512;
}
 
 out:
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] [MMC-4.5] Disable emulation

2012-05-16 Thread Saugata Das
On 17 May 2012 10:17, Saugata Das  wrote:
> On 17 May 2012 09:04, Namjae Jeon  wrote:
>> 2012/5/17, Saugata Das :
>>> On 17 May 2012 06:35, Namjae Jeon  wrote:
>>>> 2012/5/17, Saugata Das :
>>>>> From: Saugata Das 
>>>>>
>>>>> This patch adds the support for large sector size of 4KB by disabling
>>>>> emulation.
>>>>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>>>>> mmc_blk_alloc_req.
>>>>>
>>>>> In order to use this patch for 4KB sector size, ensure that
>>>>> USE_NATIVE_SECTOR
>>>>> is enabled, partition table is 4KB sector size aligned and file system
>>>>> block
>>>>> size is 4KB.
>>>> If you change native 4K from 512B emulation, filesystem sector size is
>>>> also 4KB align as well block size.
>>>> because default block size of most of filesystem is 4KB, but
>>>> filesystem sector size is 512B,
>>>> So filesystem corruption can be occured on native 4K device.
>>>>>
>>>
>>> I have tested ext4 with 4KB block size and I did not see an instance
>>> where it requested 512B.
>> -> yes, you can not see it, because when formating parittion, sector
>> size is set to 4K by I/O topology. As you know, several filesystems
>> can be used on eMMC not only Ext4. You should mention filesystem
>> sector size align in changelog.
>
> I will add the remark that file system block and sector size should be
> 4KB multiple.
>
>>> For sure, if someone is using file system with 512B sector on eMMC
>>> then the USE_NATIVE_SECTOR should not be enabled.
>> -> it will be the reason about below my question.
>>>
>>> The idea behind the patch is, MMC driver should notify the sector size
>>> information in a generic manner to file system. So, we depend here on
>>> ext_csd.data_sector_size, which should work in both 512B and 4KB case.
>>>
>>>
>>>>> Signed-off-by: Saugata Das 
>>>>> ---
>>>>>  drivers/mmc/card/block.c |   16 ++--
>>>>>  drivers/mmc/core/mmc.c   |    2 ++
>>>>>  2 files changed, 16 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>>> index 91cda75..b4d0eb1 100644
>>>>> --- a/drivers/mmc/card/block.c
>>>>> +++ b/drivers/mmc/card/block.c
>>>>> @@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>>>>> *mq,
>>>>> struct request *rqc)
>>>>>       int ret = 1, disable_multi = 0, retry = 0, type;
>>>>>       enum mmc_blk_status status;
>>>>>       struct mmc_queue_req *mq_rq;
>>>>> -     struct request *req;
>>>>> +     struct request *req = rqc;
>>>>>       struct mmc_async_req *areq;
>>>>>
>>>>>       if (!rqc && !mq->mqrq_prev->req)
>>>>> @@ -1292,6 +1292,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>>>>> *mq,
>>>>> struct request *rqc)
>>>>>
>>>>>       do {
>>>>>               if (rqc) {
>>>>> +
>>>>> +                     /*
>>>>> +                       * When 4KB native sector is enabled, single
>>>>> block
>>>>> +                       * read or write is not allowed
>>>>> +                       */
>>>>> +                     if ((brq->data.blocks == 1) &&
>>>>> +                             (card->ext_csd.data_sector_size == 4096))
>>>>> +                             goto cmd_abort;
>>>>                                               Why did you add this
>>>> code in any case ?
>>>>
>>>
>>> This was pointed during the previous review that with 4KB sector mode,
>>> 512B transfer is not allowed. So, this check has been added here.
>> -> I think that you should add error log to inform user error case.
>
> I will add pr_err here. I will also modify the condition
> (brq->data.blocks == 1)  to
> (brq->data.blocks % 4)
>

Oops. It will be (brq->data.blocks % 8)

>
>>>
>>>>>                       mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
>>>>>                       areq = &mq->mqrq_cur->mmc_active;
>>>>>               } else
>&g

Re: [PATCH 1/2] [MMC-4.5] Disable emulation

2012-05-16 Thread Saugata Das
On 17 May 2012 09:04, Namjae Jeon  wrote:
> 2012/5/17, Saugata Das :
>> On 17 May 2012 06:35, Namjae Jeon  wrote:
>>> 2012/5/17, Saugata Das :
>>>> From: Saugata Das 
>>>>
>>>> This patch adds the support for large sector size of 4KB by disabling
>>>> emulation.
>>>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>>>> mmc_blk_alloc_req.
>>>>
>>>> In order to use this patch for 4KB sector size, ensure that
>>>> USE_NATIVE_SECTOR
>>>> is enabled, partition table is 4KB sector size aligned and file system
>>>> block
>>>> size is 4KB.
>>> If you change native 4K from 512B emulation, filesystem sector size is
>>> also 4KB align as well block size.
>>> because default block size of most of filesystem is 4KB, but
>>> filesystem sector size is 512B,
>>> So filesystem corruption can be occured on native 4K device.
>>>>
>>
>> I have tested ext4 with 4KB block size and I did not see an instance
>> where it requested 512B.
> -> yes, you can not see it, because when formating parittion, sector
> size is set to 4K by I/O topology. As you know, several filesystems
> can be used on eMMC not only Ext4. You should mention filesystem
> sector size align in changelog.

I will add the remark that file system block and sector size should be
4KB multiple.

>> For sure, if someone is using file system with 512B sector on eMMC
>> then the USE_NATIVE_SECTOR should not be enabled.
> -> it will be the reason about below my question.
>>
>> The idea behind the patch is, MMC driver should notify the sector size
>> information in a generic manner to file system. So, we depend here on
>> ext_csd.data_sector_size, which should work in both 512B and 4KB case.
>>
>>
>>>> Signed-off-by: Saugata Das 
>>>> ---
>>>>  drivers/mmc/card/block.c |   16 ++--
>>>>  drivers/mmc/core/mmc.c   |    2 ++
>>>>  2 files changed, 16 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>> index 91cda75..b4d0eb1 100644
>>>> --- a/drivers/mmc/card/block.c
>>>> +++ b/drivers/mmc/card/block.c
>>>> @@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>>>> *mq,
>>>> struct request *rqc)
>>>>       int ret = 1, disable_multi = 0, retry = 0, type;
>>>>       enum mmc_blk_status status;
>>>>       struct mmc_queue_req *mq_rq;
>>>> -     struct request *req;
>>>> +     struct request *req = rqc;
>>>>       struct mmc_async_req *areq;
>>>>
>>>>       if (!rqc && !mq->mqrq_prev->req)
>>>> @@ -1292,6 +1292,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
>>>> *mq,
>>>> struct request *rqc)
>>>>
>>>>       do {
>>>>               if (rqc) {
>>>> +
>>>> +                     /*
>>>> +                       * When 4KB native sector is enabled, single
>>>> block
>>>> +                       * read or write is not allowed
>>>> +                       */
>>>> +                     if ((brq->data.blocks == 1) &&
>>>> +                             (card->ext_csd.data_sector_size == 4096))
>>>> +                             goto cmd_abort;
>>>                                               Why did you add this
>>> code in any case ?
>>>
>>
>> This was pointed during the previous review that with 4KB sector mode,
>> 512B transfer is not allowed. So, this check has been added here.
> -> I think that you should add error log to inform user error case.

I will add pr_err here. I will also modify the condition
(brq->data.blocks == 1)  to
(brq->data.blocks % 4)


>>
>>>>                       mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
>>>>                       areq = &mq->mqrq_cur->mmc_active;
>>>>               } else
>>>> @@ -1539,7 +1547,11 @@ static struct mmc_blk_data
>>>> *mmc_blk_alloc_req(struct
>>>> mmc_card *card,
>>>>       snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>>>                "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>>>
>>>> -     blk_queue_logical_block_size(md->queue.queue, 512);
>>>> +     if (mmc_card_mmc(card))
>>

Re: [PATCH 1/2] [MMC-4.5] Disable emulation

2012-05-16 Thread Saugata Das
On 17 May 2012 06:35, Namjae Jeon  wrote:
> 2012/5/17, Saugata Das :
>> From: Saugata Das 
>>
>> This patch adds the support for large sector size of 4KB by disabling
>> emulation.
>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>> mmc_blk_alloc_req.
>>
>> In order to use this patch for 4KB sector size, ensure that
>> USE_NATIVE_SECTOR
>> is enabled, partition table is 4KB sector size aligned and file system
>> block
>> size is 4KB.
> If you change native 4K from 512B emulation, filesystem sector size is
> also 4KB align as well block size.
> because default block size of most of filesystem is 4KB, but
> filesystem sector size is 512B,
> So filesystem corruption can be occured on native 4K device.
>>

I have tested ext4 with 4KB block size and I did not see an instance
where it requested 512B.
For sure, if someone is using file system with 512B sector on eMMC
then the USE_NATIVE_SECTOR should not be enabled.

The idea behind the patch is, MMC driver should notify the sector size
information in a generic manner to file system. So, we depend here on
ext_csd.data_sector_size, which should work in both 512B and 4KB case.


>> Signed-off-by: Saugata Das 
>> ---
>>  drivers/mmc/card/block.c |   16 ++--
>>  drivers/mmc/core/mmc.c   |    2 ++
>>  2 files changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index 91cda75..b4d0eb1 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq,
>> struct request *rqc)
>>       int ret = 1, disable_multi = 0, retry = 0, type;
>>       enum mmc_blk_status status;
>>       struct mmc_queue_req *mq_rq;
>> -     struct request *req;
>> +     struct request *req = rqc;
>>       struct mmc_async_req *areq;
>>
>>       if (!rqc && !mq->mqrq_prev->req)
>> @@ -1292,6 +1292,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq,
>> struct request *rqc)
>>
>>       do {
>>               if (rqc) {
>> +
>> +                     /*
>> +                       * When 4KB native sector is enabled, single block
>> +                       * read or write is not allowed
>> +                       */
>> +                     if ((brq->data.blocks == 1) &&
>> +                             (card->ext_csd.data_sector_size == 4096))
>> +                             goto cmd_abort;
>                                               Why did you add this
> code in any case ?
>

This was pointed during the previous review that with 4KB sector mode,
512B transfer is not allowed. So, this check has been added here.

>>                       mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
>>                       areq = &mq->mqrq_cur->mmc_active;
>>               } else
>> @@ -1539,7 +1547,11 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct
>> mmc_card *card,
>>       snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>                "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>
>> -     blk_queue_logical_block_size(md->queue.queue, 512);
>> +     if (mmc_card_mmc(card))
>> +             blk_queue_logical_block_size(md->queue.queue,
>> +                     card->ext_csd.data_sector_size);
>> +     else
>> +             blk_queue_logical_block_size(md->queue.queue, 512);
>>       set_capacity(md->disk, size);
>>
>>       if (mmc_host_cmd23(card->host)) {
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index 7268c26..11444c6 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -516,6 +516,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8
>> *ext_csd)
>>               } else {
>>                       card->ext_csd.data_tag_unit_size = 0;
>>               }
>> +     } else {
>> +             card->ext_csd.data_sector_size = 512;
>>       }
>>
>>  out:
>> --
>> 1.7.4.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-16 Thread Saugata Das
From: Saugata Das 

In this patch, we add utility to disable emulation mode in the eMMC-4.5.
This is done to increase the data sector size to 4KB.

Signed-off-by: Saugata Das 

changes in v2:
Review rework based on comments from Subhash
---
 mmc.c  |6 ++
 mmc.h  |   10 ++
 mmc_cmds.c |   51 +++
 mmc_cmds.h |1 +
 4 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/mmc.c b/mmc.c
index c27fc24..ebc7ab2 100644
--- a/mmc.c
+++ b/mmc.c
@@ -65,6 +65,12 @@ static struct Command commands[] = {
"Set the eMMC writeprotect status of .",
  NULL
},
+   { do_disable_512B_emulation, -1,
+ "disable 512B emulation", "\n"
+   "Set the eMMC data sector size to 4KB by disabling emulation 
.",
+ NULL
+   },
+
{ 0, 0, 0, 0 }
 };
 
diff --git a/mmc.h b/mmc.h
index 3af36f1..34c31d3 100644
--- a/mmc.h
+++ b/mmc.h
@@ -35,6 +35,16 @@
 #define EXT_CSD_PART_SWITCH_TIME   199
 #define EXT_CSD_BOOT_CFG   179
 #define EXT_CSD_BOOT_WP173
+#define EXT_CSD_WR_REL_PARAM   166
+#define EXT_CSD_NATIVE_SECTOR_SIZE 63 /* R */
+#define EXT_CSD_USE_NATIVE_SECTOR  62 /* R/W */
+#define EXT_CSD_DATA_SECTOR_SIZE   61 /* R */
+
+/*
+ * WR_REL_PARAM field definitions
+ */
+#define HS_CTRL_REL(1<<0)
+#define EN_REL_WR  (1<<2)
 
 /*
  * EXT_CSD field definitions
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 4562cef..f0e64c9 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -168,6 +168,57 @@ int do_writeprotect_set(int nargs, char **argv)
return ret;
 }
 
+
+int do_disable_512B_emulation(int nargs, char **argv)
+{
+   __u8 ext_csd[512], native_sector_size, data_sector_size, wr_rel_param;
+   int fd, ret;
+   char *device;
+
+   CHECK(nargs != 2, "Usage: mmc \n", exit(1));
+
+   device = argv[1];
+
+   fd = open(device, O_RDWR);
+   if (fd < 0) {
+   perror("open");
+   exit(1);
+   }
+
+   ret = read_extcsd(fd, ext_csd);
+   if (ret) {
+   fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+   exit(1);
+   }
+
+   wr_rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+   native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
+   data_sector_size = ext_csd[EXT_CSD_DATA_SECTOR_SIZE];
+
+   if (native_sector_size &&
+   !data_sector_size &&
+   (wr_rel_param & EN_REL_WR)) {
+   ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1);
+
+   if (ret) {
+   fprintf(stderr, "Could not write 0x%02x to "
+   "EXT_CSD[%d] in %s\n",
+   1, EXT_CSD_BOOT_WP, device);
+   exit(1);
+   }
+   printf("MMC disable 512B emulation successful\n"
+   "Now reset the device to switch to 4KB "
+   "native sector mode\n");
+   } else if (native_sector_size && data_sector_size) {
+   printf("MMC already disabled 512B emulation mode\n");
+   } else {
+   printf("MMC does not support disabling 512B emulation mode\n");
+   }
+
+   return ret;
+}
+
+
 int do_read_extcsd(int nargs, char **argv)
 {
__u8 ext_csd[512], ext_csd_rev, reg;
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 66e9acb..56f46d7 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv);
 int do_write_extcsd(int nargs, char **argv);
 int do_writeprotect_get(int nargs, char **argv);
 int do_writeprotect_set(int nargs, char **argv);
+int do_disable_512B_emulation(int nargs, char **argv);
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] [MMC-4.5] Disable emulation

2012-05-16 Thread Saugata Das
From: Saugata Das 

This patch adds the support for large sector size of 4KB by disabling emulation.
This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
mmc_blk_alloc_req.

In order to use this patch for 4KB sector size, ensure that USE_NATIVE_SECTOR
is enabled, partition table is 4KB sector size aligned and file system block
size is 4KB.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |   16 ++--
 drivers/mmc/core/mmc.c   |2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 91cda75..b4d0eb1 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1284,7 +1284,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
int ret = 1, disable_multi = 0, retry = 0, type;
enum mmc_blk_status status;
struct mmc_queue_req *mq_rq;
-   struct request *req;
+   struct request *req = rqc;
struct mmc_async_req *areq;
 
if (!rqc && !mq->mqrq_prev->req)
@@ -1292,6 +1292,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
 
do {
if (rqc) {
+
+   /*
+ * When 4KB native sector is enabled, single block
+ * read or write is not allowed
+ */
+   if ((brq->data.blocks == 1) &&
+   (card->ext_csd.data_sector_size == 4096))
+   goto cmd_abort;
mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
areq = &mq->mqrq_cur->mmc_active;
} else
@@ -1539,7 +1547,11 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
 "mmcblk%d%s", md->name_idx, subname ? subname : "");
 
-   blk_queue_logical_block_size(md->queue.queue, 512);
+   if (mmc_card_mmc(card))
+   blk_queue_logical_block_size(md->queue.queue,
+   card->ext_csd.data_sector_size);
+   else
+   blk_queue_logical_block_size(md->queue.queue, 512);
set_capacity(md->disk, size);
 
if (mmc_host_cmd23(card->host)) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7268c26..11444c6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -516,6 +516,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
} else {
card->ext_csd.data_tag_unit_size = 0;
}
+   } else {
+   card->ext_csd.data_sector_size = 512;
}
 
 out:
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/3] mmc: Context support

2012-05-16 Thread Saugata Das
From: Saugata Das 

This patch implements the context ID support at MMC layer. From file system
(ext4), the context is passed in the request structure. At MMC layer the
context is retrieved from the request structure and then used in the CMD23
argument. Since number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC contexts. When the REQ_SYNC or REQ_FLUSH
flag is set, the context is flushed or sync'ed, in which the context is
closed so that the data blocks are safely written out to non-volatile memory
and then the context is opened again.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |   35 +-
 drivers/mmc/core/core.c  |   72 ++
 drivers/mmc/core/mmc.c   |   28 ++
 include/linux/mmc/card.h |4 ++
 include/linux/mmc/core.h |4 ++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |3 ++
 7 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dabec55..914f942 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -958,6 +958,15 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, 
struct request *req)
struct mmc_card *card = md->queue.card;
int ret = 0;
 
+   /*
+* The flush command is a synchronization point from file system.
+* The contexts are flushed here to ensure that the data written
+* in the open contexts are saved reliably in non-volatile media
+*/
+   ret = mmc_flush_contexts(card);
+   if (ret)
+   ret = -EIO;
+
ret = mmc_flush_cache(card);
if (ret)
ret = -EIO;
@@ -1207,11 +1216,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
 */
if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
(do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
-do_data_tag)) {
+do_data_tag || (card->ext_csd.max_context_id > 0))) {
+   int context_id = (req->context &&
+   card->ext_csd.max_context_id) ?
+   (req->context % card->ext_csd.max_context_id + 1) :
+   0;
brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
brq->sbc.arg = brq->data.blocks |
(do_rel_wr ? (1 << 31) : 0) |
-   (do_data_tag ? (1 << 29) : 0);
+   (do_data_tag ? (1 << 29) : 0) |
+   (!do_data_tag ? (context_id << 25) : 0);
brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
brq->mrq.sbc = &brq->sbc;
}
@@ -1440,6 +1454,23 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct 
request *req)
mmc_blk_issue_rw_rq(mq, NULL);
ret = mmc_blk_issue_flush(mq, req);
} else {
+   if (req && (req->cmd_flags & REQ_SYNC) &&
+   req->context && card->ext_csd.max_context_id) {
+   int context_cfg_id = (req->context) ?
+   req->context % card->ext_csd.max_context_id : 0;
+   /*
+* The SYNC command is a synchronization point from
+* file system. The relevent context is sync'ed here
+* to ensure that the data written in the open context
+* are saved reliably in non-volatile media
+*/
+   if (card->host->areq)
+   mmc_blk_issue_rw_rq(mq, NULL);
+   mmc_sync_context(card, context_cfg_id);
+   /* this write will go without context to ensure
+  that it is reliably written */
+   req->context = 0;
+   }
ret = mmc_blk_issue_rw_rq(mq, req);
}
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ba821fe..728145a 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2262,6 +2262,78 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 }
 EXPORT_SYMBOL(mmc_cache_ctrl);
 
+/*
+ * Synchronize a context by first closing the context and then
+ * opening it
+ */
+int mmc_sync_context(struct mmc_card *card, int context_id)
+{
+   int err = 0;
+
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CONTEXT_CONF + context_id,
+   0x0, card->ext_csd.generic_cmd6_time);
+
+   if (err)
+   return err;
+
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CONTEXT_CONF + context_id,
+   0x3, card->ext_csd.generic_cmd6_time);
+
+

[RFC 2/3] ext4: Context support

2012-05-16 Thread Saugata Das
From: Saugata Das 

On eMMC and UFS devices there is a new feature of setting context with
each read or write. The idea is to classify the data from different files
and apply the realibility on the complete file instead of individual writes.
On ext4 file system, the inode number of the file is passed as b_context
in the bh structure during write and via the get_context callback function
during read. Since number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC context.

Signed-off-by: Saugata Das 
---
 fs/ext4/inode.c   |   33 +
 fs/ext4/page-io.c |1 +
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 754fe77..2667396 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -790,6 +790,21 @@ static int do_journal_get_write_access(handle_t *handle,
return ret;
 }
 
+/* Get the context of the buffer within the underlying storage device */
+static int ext4_get_context(struct page *page)
+{
+   if (page && page->mapping && page->mapping->host)
+   return page->mapping->host->i_ino;
+   else
+   return 0;
+}
+
+static int ext4_set_buffer_context(handle_t *handle, struct buffer_head *bh)
+{
+   bh->b_context = ext4_get_context(bh->b_page);
+   return 0;
+}
+
 static int ext4_get_block_write(struct inode *inode, sector_t iblock,
   struct buffer_head *bh_result, int create);
 static int ext4_write_begin(struct file *file, struct address_space *mapping,
@@ -843,6 +858,11 @@ retry:
from, to, NULL, do_journal_get_write_access);
}
 
+   if (!ret && walk_page_buffers(NULL, page_buffers(page),
+   from, to, NULL, ext4_set_buffer_context)) {
+   ext4_warning(inode->i_sb, "Couldn't set context\n");
+   }
+
if (ret) {
unlock_page(page);
page_cache_release(page);
@@ -2394,8 +2414,11 @@ static int ext4_da_write_begin(struct file *file, struct 
address_space *mapping,
pgoff_t index;
struct inode *inode = mapping->host;
handle_t *handle;
+   unsigned from, to;
 
index = pos >> PAGE_CACHE_SHIFT;
+   from = pos & (PAGE_CACHE_SIZE - 1);
+   to = from + len;
 
if (ext4_nonda_switch(inode->i_sb)) {
*fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
@@ -2444,6 +2467,12 @@ retry:
 
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
+
+   if (walk_page_buffers(NULL, page_buffers(page),
+   from, to, NULL, ext4_set_buffer_context)) {
+   ext4_warning(inode->i_sb, "Couldn't set context\n");
+   }
+
 out:
return ret;
 }
@@ -3040,6 +3069,7 @@ static const struct address_space_operations 
ext4_ordered_aops = {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_writeback_aops = {
@@ -3055,6 +3085,7 @@ static const struct address_space_operations 
ext4_writeback_aops = {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_journalled_aops = {
@@ -3070,6 +3101,7 @@ static const struct address_space_operations 
ext4_journalled_aops = {
.direct_IO  = ext4_direct_IO,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 static const struct address_space_operations ext4_da_aops = {
@@ -3086,6 +3118,7 @@ static const struct address_space_operations ext4_da_aops 
= {
.migratepage= buffer_migrate_page,
.is_partially_uptodate  = block_is_partially_uptodate,
.error_remove_page  = generic_error_remove_page,
+   .get_context= ext4_get_context,
 };
 
 void ext4_set_aops(struct inode *inode)
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index dcdeef1..bf1381e 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -296,6 +296,7 @@ static int io_submit_init(struct ext4_io_submit *io,
bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
bio->bi_bdev = bh->b_bdev;
+   bio->bi_context = bh->b_context;
bio->bi_private = io->io_end = io_end;
bio->bi_end_io = ext4_end_bio;
 
--

[RFC 1/3] block: Context support

2012-05-16 Thread Saugata Das
From: Saugata Das 

On eMMC and UFS devices there is a new feature of setting context with each
read or write. The idea is to classify the data from different files and
apply the realibility on the complete file instead of individual writes,
which helps in performance. A new address space operation has been a added
to get the context from file system and set up the bi_context field in bio.
Then we need to ensure that bio from different contexts are not merged. The
context is then passed to the underlying driver as part of the read or write
request. Since the number of MMC contexts is limited, multiple file system
contexts are mapped to single MMC context.

Signed-off-by: Saugata Das 
---
 block/blk-core.c|1 +
 block/blk-merge.c   |3 +++
 fs/mpage.c  |   12 
 include/linux/blk_types.h   |1 +
 include/linux/blkdev.h  |1 +
 include/linux/buffer_head.h |2 ++
 include/linux/fs.h  |1 +
 7 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 1f61b74..274e05d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1309,6 +1309,7 @@ void init_request_from_bio(struct request *req, struct 
bio *bio)
req->errors = 0;
req->__sector = bio->bi_sector;
req->ioprio = bio_prio(bio);
+   req->context = bio->bi_context;
blk_rq_bio_prep(req->q, req, bio);
 }
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 160035f..ed70d56 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -497,6 +497,9 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
if (bio_integrity(bio) != blk_integrity_rq(rq))
return false;
 
+   if (bio->bi_context != rq->bio->bi_context)
+   return false;
+
return true;
 }
 
diff --git a/fs/mpage.c b/fs/mpage.c
index 0face1c..4889842 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -293,6 +293,12 @@ alloc_new:
goto confused;
}
 
+   if (page && page->mapping && page->mapping->a_ops &&
+   page->mapping->a_ops->get_context)
+   bio->bi_context = page->mapping->a_ops->get_context(page);
+   else
+   bio->bi_context = 0;
+
length = first_hole << blkbits;
if (bio_add_page(bio, page, length, 0) < length) {
bio = mpage_bio_submit(READ, bio);
@@ -581,6 +587,12 @@ alloc_new:
goto confused;
}
 
+   if (page && page->mapping && page->mapping->a_ops &&
+   page->mapping->a_ops->get_context)
+   bio->bi_context = page->mapping->a_ops->get_context(page);
+   else
+   bio->bi_context = 0;
+
/*
 * Must try to add the page before marking the buffer clean or
 * the confused fail path above (OOM) will be very confused when
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 4053cbd..f3ac448 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -42,6 +42,7 @@ struct bio {
 
unsigned short  bi_vcnt;/* how many bio_vec's */
unsigned short  bi_idx; /* current index into bvl_vec */
+   unsigned long   bi_context; /* context of this bio */
 
/* Number of segments in this BIO after
 * physical address coalescing is performed.
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2aa2466..0dd9a08 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -167,6 +167,7 @@ struct request {
struct list_head timeout_list;
unsigned int timeout;
int retries;
+   unsigned long context;  /* context of this request */
 
/*
 * completion callback.
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 13bba17..0776564 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -72,6 +72,8 @@ struct buffer_head {
struct list_head b_assoc_buffers; /* associated with another mapping */
struct address_space *b_assoc_map;  /* mapping this buffer is
   associated with */
+   unsigned long   b_context; /* context for this buffer within the
+   storage device */
atomic_t b_count;   /* users using this buffer_head */
 };
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8de6755..4b379d8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -626,6 +626,7 @@ struct address_space_operations {
int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
unsigned long);
int (*error_remove_page)(struct address_space *, struct pag

Re: [RFC 1/2] [MMC-4.5] Disable emulation

2012-05-15 Thread Saugata Das
On 15 May 2012 15:47, S, Venkatraman  wrote:
> On Tue, May 15, 2012 at 12:10 PM, Subhash Jadavani
>  wrote:
>> On 5/14/2012 8:21 PM, Saugata Das wrote:
>>>
>>> On 14 May 2012 15:55, Subhash Jadavani  wrote:
>>>>
>>>> On 5/9/2012 8:18 PM, Saugata Das wrote:
>>>>>
>>>>> From: Saugata Das
>>>>>
>>>>> This patch adds the support for large sector size of 4KB by disabling
>>>>> emulation.
>>>>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>>>>> mmc_blk_alloc_req.
>>>>>
>>>>> In order to use this patch for 4KB sector size, ensure that
>>>>> USE_NATIVE_SECTOR
>>>>> is enabled, partition table is 4KB sector size aligned and file system
>>>>> block
>>>>> size is 4KB.
>>>>>
>>>>> Signed-off-by: Saugata Das
>>>>> ---
>>>>>  drivers/mmc/card/block.c |    6 +-
>>>>>  drivers/mmc/core/mmc.c   |    2 ++
>>>>>  2 files changed, 7 insertions(+), 1 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>>> index a7c75d8..0e54118e 100644
>>>>> --- a/drivers/mmc/card/block.c
>>>>> +++ b/drivers/mmc/card/block.c
>>>>> @@ -1517,7 +1517,11 @@ static struct mmc_blk_data
>>>>> *mmc_blk_alloc_req(struct mmc_card *card,
>>>>>        snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>>>>                 "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>>>>
>>>>> -       blk_queue_logical_block_size(md->queue.queue, 512);
>>>>> +       if (mmc_card_mmc(card))
>>>>> +               blk_queue_logical_block_size(md->queue.queue,
>>>>> +                       card->ext_csd.data_sector_size);
>>>>
>>>> Shouldn't we also set the physical block size to NATIVE_SECTOR_SIZE
>>>> value?
>>>>
>>> The physical block size gets set from blk_queue_logical_block_size
>>>
>>>> Other question,
>>>> Did you find any eMMC device which 4K native sector size? If yes, please
>>>> share the test results.
>>>>
>>> I have not yet seen the eMMC device implementing 4KB sector. But MMC
>>> vendors are promising this feature, so I prepared this patch. So far,
>>> I have tested by setting "data_sector_size" to 4KB (doing a hack in
>>> mmc_read_ext_csd), configuring file system to have 4KB block size and
>>> mounting it.
>>
>> Ok. So basically you are emulating the 512B native sector device as 4K
>> native sector device and always read/write this device in 4K granularity. So
>> this is just a proof of concept that setting the block queue logical sector
>> size to 4K works or not?
>> Are vendors promising any performance improvement if we run the device in 4K
>> sector size mode rather than emulation mode?
>>
>> I have few other doubts (from specification point of view) when the device
>> starts running in native sector size mode:
>>
>> 1. According spec, "A large sector device shall not support partial access
>> and shall not support reliable write mode EN_REL_WR=0."
>>        Shouldn't this patch make ensure this?
>>
>> 2.  Some internal sizes reported by the device may change after successfully
>> disabling of the emulation mode.
>>        Shouldn't  we take of this as well?
> This would be because if a single 512byte sector was marked as bad
> (unusable) initially, the entire
> aligned 4K block would be marked as bad now after switching to 4K
> sector size, resulting in a slight capacity shrinkage.
>  This would only matter if the switch happens for a fairly old
> device. Typically, the sector size change should happen during factory
> initialization, so there wouldn't be too many bad blocks, so it
> shouldn't be much of an issue now.
>  Of course, this is just one aspect of a problem for the "dynamic
> device capacity" feature of eMMC4.5, and can be solved if we get to
> that..
>

If 512byte sector becomes bad, then the complete NAND block (much
larger than 4KB) will be marked bad. As such, there should be no
difference in terms of amount of shrinkage. But yes, we need to start
thinking about "dynamic device capacity" once the number of bad NAND
blocks exceeds what eMMC can afford.

>
>>
>> 3. After a successful disabling 

Re: [RFC 1/2] [MMC-4.5] Disable emulation

2012-05-15 Thread Saugata Das
On 15 May 2012 12:10, Subhash Jadavani  wrote:
> On 5/14/2012 8:21 PM, Saugata Das wrote:
>>
>> On 14 May 2012 15:55, Subhash Jadavani  wrote:
>>>
>>> On 5/9/2012 8:18 PM, Saugata Das wrote:
>>>>
>>>> From: Saugata Das
>>>>
>>>> This patch adds the support for large sector size of 4KB by disabling
>>>> emulation.
>>>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>>>> mmc_blk_alloc_req.
>>>>
>>>> In order to use this patch for 4KB sector size, ensure that
>>>> USE_NATIVE_SECTOR
>>>> is enabled, partition table is 4KB sector size aligned and file system
>>>> block
>>>> size is 4KB.
>>>>
>>>> Signed-off-by: Saugata Das
>>>> ---
>>>>  drivers/mmc/card/block.c |    6 +-
>>>>  drivers/mmc/core/mmc.c   |    2 ++
>>>>  2 files changed, 7 insertions(+), 1 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>> index a7c75d8..0e54118e 100644
>>>> --- a/drivers/mmc/card/block.c
>>>> +++ b/drivers/mmc/card/block.c
>>>> @@ -1517,7 +1517,11 @@ static struct mmc_blk_data
>>>> *mmc_blk_alloc_req(struct mmc_card *card,
>>>>        snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>>>                 "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>>>
>>>> -       blk_queue_logical_block_size(md->queue.queue, 512);
>>>> +       if (mmc_card_mmc(card))
>>>> +               blk_queue_logical_block_size(md->queue.queue,
>>>> +                       card->ext_csd.data_sector_size);
>>>
>>> Shouldn't we also set the physical block size to NATIVE_SECTOR_SIZE
>>> value?
>>>
>> The physical block size gets set from blk_queue_logical_block_size
>>
>>> Other question,
>>> Did you find any eMMC device which 4K native sector size? If yes, please
>>> share the test results.
>>>
>> I have not yet seen the eMMC device implementing 4KB sector. But MMC
>> vendors are promising this feature, so I prepared this patch. So far,
>> I have tested by setting "data_sector_size" to 4KB (doing a hack in
>> mmc_read_ext_csd), configuring file system to have 4KB block size and
>> mounting it.
>
> Ok. So basically you are emulating the 512B native sector device as 4K
> native sector device and always read/write this device in 4K granularity. So
> this is just a proof of concept that setting the block queue logical sector
> size to 4K works or not?

Yes and it works. Note that, even the partition tables need to be 4KB aligned.

> Are vendors promising any performance improvement if we run the device in 4K
> sector size mode rather than emulation mode?
>

Atleast from the explanation in the spec on emulation mode, this
promises to provide some improvement. Some vendors may already have
some proprietary optimization to optimize access which are not 4KB
aligned. But lets target this 4KB alignment to have a good performance
across devices.

> I have few other doubts (from specification point of view) when the device
> starts running in native sector size mode:
>
> 1. According spec, "A large sector device shall not support partial access
> and shall not support reliable write mode EN_REL_WR=0."
>        Shouldn't this patch make ensure this?
>

Yes, May be, we should add a check in mmc-util i.e. set
USE_NATIVE_SECTOR only if EN_REL_WR = 1 .


> 2.  Some internal sizes reported by the device may change after successfully
> disabling of the emulation mode.
>        Shouldn't  we take of this as well?
>

Which parameter size will change ? I did not come across such remark
in the specification.


> 3. After a successful disabling of the emulation mode, the content of the
> User Data Area is undefined.
>        If the contents of the user data area is undefined after disabling
> the emulation mode, i don't think device will be able to boot to kernel
> after power cycle. So does this mean we have to flash the kernel/file system
> images
>        again? Basically i don't see a use of disabling the emulation mode
> from kernel. It should be done by basic build/image flashing utility which
> could flash the images after setting the use_native_sector field and power
> cycle.

Kernel is not disabling emulation mode. The mmc-util tool is doing it.
You are right, the flashing utility will disable the emulation mode
(mmc-util change can be used as a reference for the flashing uti

Re: [RFC 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-14 Thread Saugata Das
On 14 May 2012 16:09, Subhash Jadavani  wrote:
> On 5/9/2012 8:18 PM, Saugata Das wrote:
>>
>> From: Saugata Das
>>
>> In this patch, we add utility to disable emulation mode in the eMMC-4.5.
>> This is done to increase the data sector size to 4KB.
>>
>> Signed-off-by: Saugata Das
>> ---
>>  mmc.c      |    6 ++
>>  mmc.h      |    2 ++
>>  mmc_cmds.c |   42 ++
>>  mmc_cmds.h |    1 +
>>  4 files changed, 51 insertions(+), 0 deletions(-)
>>
>> diff --git a/mmc.c b/mmc.c
>> index c27fc24..43b95aa 100644
>> --- a/mmc.c
>> +++ b/mmc.c
>> @@ -65,6 +65,12 @@ static struct Command commands[] = {
>>                "Set the eMMC writeprotect status of.",
>>          NULL
>>        },
>> +       { do_disable_emulation, -1,
>
> can we add good name? which emulation we are disabling? It's 512B emulation
> mode, we are disabling.
>

Ok

>> +         "disable emulation", "\n"
>> +               "Set the eMMC data sector size to 4KB by disabling
>> emulation.",
>> +         NULL
>> +       },
>> +
>>        { 0, 0, 0, 0 }
>>  };
>>
>> diff --git a/mmc.h b/mmc.h
>> index 3af36f1..a2050fa 100644
>> --- a/mmc.h
>> +++ b/mmc.h
>> @@ -35,6 +35,8 @@
>>  #define EXT_CSD_PART_SWITCH_TIME      199
>>  #define EXT_CSD_BOOT_CFG              179
>>  #define EXT_CSD_BOOT_WP                       173
>> +#define EXT_CSD_NATIVE_SECTOR_SIZE     63 /* R */
>> +#define EXT_CSD_NATIVE_SECTOR  62 /* R/W */
>
> Can we name this as EXT_CSD_USE_NATIVE_SECTOR?
>

Ok

>>
>>  /*
>>   * EXT_CSD field definitions
>> diff --git a/mmc_cmds.c b/mmc_cmds.c
>> index 4562cef..2713ccd 100644
>> --- a/mmc_cmds.c
>> +++ b/mmc_cmds.c
>> @@ -168,6 +168,48 @@ int do_writeprotect_set(int nargs, char **argv)
>>        return ret;
>>  }
>>
>> +
>> +int do_disable_emulation(int nargs, char **argv)
>> +{
>> +       __u8 ext_csd[512], native_sector_size;
>> +       int fd, ret;
>> +       char *device;
>> +
>> +       CHECK(nargs != 2, "Usage: mmc\n", exit(1));
>> +
>> +       device = argv[1];
>> +
>> +       fd = open(device, O_RDWR);
>> +       if (fd<  0) {
>> +               perror("open");
>> +               exit(1);
>> +       }
>> +
>> +       ret = read_extcsd(fd, ext_csd);
>> +       if (ret) {
>> +               fprintf(stderr, "Could not read EXT_CSD from %s\n",
>> device);
>> +               exit(1);
>> +       }
>> +
>> +       native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
>> +
>> +       if (native_sector_size) {
>> +               ret = write_extcsd_value(fd, EXT_CSD_NATIVE_SECTOR, 1);
>
> Just curious, how are we going to power cycle the device after setting the
> USE_NATIVE_SECTOR? because DATA_SECTOR_SIZE won't be changed to 4K until we
> explicitly power cycle after setting this field.
>

I will add a "printf" instructing the user to power cycle the eMMC at
the end of the switch.

>> +
>> +               if (ret) {
>> +                       fprintf(stderr, "Could not write 0x%02x to "
>> +                               "EXT_CSD[%d] in %s\n",
>> +                               1, EXT_CSD_BOOT_WP, device);
>> +                       exit(1);
>> +               }
>> +       } else {
>> +               printf("MMC does not support 4KB native sector\n");
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +
>>  int do_read_extcsd(int nargs, char **argv)
>>  {
>>        __u8 ext_csd[512], ext_csd_rev, reg;
>> diff --git a/mmc_cmds.h b/mmc_cmds.h
>> index 66e9acb..dd107d5 100644
>> --- a/mmc_cmds.h
>> +++ b/mmc_cmds.h
>> @@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv);
>>  int do_write_extcsd(int nargs, char **argv);
>>  int do_writeprotect_get(int nargs, char **argv);
>>  int do_writeprotect_set(int nargs, char **argv);
>> +int do_disable_emulation(int nargs, char **argv);
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-14 Thread Saugata Das
On 14 May 2012 16:20, Subhash Jadavani  wrote:
> On 5/9/2012 8:18 PM, Saugata Das wrote:
>>
>> From: Saugata Das
>>
>> In this patch, we add utility to disable emulation mode in the eMMC-4.5.
>> This is done to increase the data sector size to 4KB.
>>
>> Signed-off-by: Saugata Das
>> ---
>>  mmc.c      |    6 ++
>>  mmc.h      |    2 ++
>>  mmc_cmds.c |   42 ++
>>  mmc_cmds.h |    1 +
>>  4 files changed, 51 insertions(+), 0 deletions(-)
>>
>> diff --git a/mmc.c b/mmc.c
>> index c27fc24..43b95aa 100644
>> --- a/mmc.c
>> +++ b/mmc.c
>> @@ -65,6 +65,12 @@ static struct Command commands[] = {
>>                "Set the eMMC writeprotect status of.",
>>          NULL
>>        },
>> +       { do_disable_emulation, -1,
>> +         "disable emulation", "\n"
>> +               "Set the eMMC data sector size to 4KB by disabling
>> emulation.",
>> +         NULL
>> +       },
>> +
>>        { 0, 0, 0, 0 }
>>  };
>>
>> diff --git a/mmc.h b/mmc.h
>> index 3af36f1..a2050fa 100644
>> --- a/mmc.h
>> +++ b/mmc.h
>> @@ -35,6 +35,8 @@
>>  #define EXT_CSD_PART_SWITCH_TIME      199
>>  #define EXT_CSD_BOOT_CFG              179
>>  #define EXT_CSD_BOOT_WP                       173
>> +#define EXT_CSD_NATIVE_SECTOR_SIZE     63 /* R */
>> +#define EXT_CSD_NATIVE_SECTOR  62 /* R/W */
>>
>>  /*
>>   * EXT_CSD field definitions
>> diff --git a/mmc_cmds.c b/mmc_cmds.c
>> index 4562cef..2713ccd 100644
>> --- a/mmc_cmds.c
>> +++ b/mmc_cmds.c
>> @@ -168,6 +168,48 @@ int do_writeprotect_set(int nargs, char **argv)
>>        return ret;
>>  }
>>
>> +
>> +int do_disable_emulation(int nargs, char **argv)
>> +{
>> +       __u8 ext_csd[512], native_sector_size;
>> +       int fd, ret;
>> +       char *device;
>> +
>> +       CHECK(nargs != 2, "Usage: mmc\n", exit(1));
>> +
>> +       device = argv[1];
>> +
>> +       fd = open(device, O_RDWR);
>> +       if (fd<  0) {
>> +               perror("open");
>> +               exit(1);
>> +       }
>> +
>> +       ret = read_extcsd(fd, ext_csd);
>> +       if (ret) {
>> +               fprintf(stderr, "Could not read EXT_CSD from %s\n",
>> device);
>> +               exit(1);
>> +       }
>> +
>> +       native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
>> +
>> +       if (native_sector_size) {
>
> Before setting the use_native_sector field, can you also check if
> NATIVE_SECTOR_SIZE and DATA_SECTOR_SIZE fields are different. If they are
> same then there is no need to set the USE_NATIVE_SECTOR size field.
>

Ok

>
>> +               ret = write_extcsd_value(fd, EXT_CSD_NATIVE_SECTOR, 1);
>> +
>> +               if (ret) {
>> +                       fprintf(stderr, "Could not write 0x%02x to "
>> +                               "EXT_CSD[%d] in %s\n",
>> +                               1, EXT_CSD_BOOT_WP, device);
>> +                       exit(1);
>> +               }
>> +       } else {
>> +               printf("MMC does not support 4KB native sector\n");
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +
>>  int do_read_extcsd(int nargs, char **argv)
>>  {
>>        __u8 ext_csd[512], ext_csd_rev, reg;
>> diff --git a/mmc_cmds.h b/mmc_cmds.h
>> index 66e9acb..dd107d5 100644
>> --- a/mmc_cmds.h
>> +++ b/mmc_cmds.h
>> @@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv);
>>  int do_write_extcsd(int nargs, char **argv);
>>  int do_writeprotect_get(int nargs, char **argv);
>>  int do_writeprotect_set(int nargs, char **argv);
>> +int do_disable_emulation(int nargs, char **argv);
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 1/2] [MMC-4.5] Disable emulation

2012-05-14 Thread Saugata Das
On 14 May 2012 15:55, Subhash Jadavani  wrote:
> On 5/9/2012 8:18 PM, Saugata Das wrote:
>>
>> From: Saugata Das
>>
>> This patch adds the support for large sector size of 4KB by disabling
>> emulation.
>> This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
>> mmc_blk_alloc_req.
>>
>> In order to use this patch for 4KB sector size, ensure that
>> USE_NATIVE_SECTOR
>> is enabled, partition table is 4KB sector size aligned and file system
>> block
>> size is 4KB.
>>
>> Signed-off-by: Saugata Das
>> ---
>>  drivers/mmc/card/block.c |    6 +-
>>  drivers/mmc/core/mmc.c   |    2 ++
>>  2 files changed, 7 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index a7c75d8..0e54118e 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -1517,7 +1517,11 @@ static struct mmc_blk_data
>> *mmc_blk_alloc_req(struct mmc_card *card,
>>        snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
>>                 "mmcblk%d%s", md->name_idx, subname ? subname : "");
>>
>> -       blk_queue_logical_block_size(md->queue.queue, 512);
>> +       if (mmc_card_mmc(card))
>> +               blk_queue_logical_block_size(md->queue.queue,
>> +                       card->ext_csd.data_sector_size);
>
> Shouldn't we also set the physical block size to NATIVE_SECTOR_SIZE value?
>

The physical block size gets set from blk_queue_logical_block_size

> Other question,
> Did you find any eMMC device which 4K native sector size? If yes, please
> share the test results.
>

I have not yet seen the eMMC device implementing 4KB sector. But MMC
vendors are promising this feature, so I prepared this patch. So far,
I have tested by setting "data_sector_size" to 4KB (doing a hack in
mmc_read_ext_csd), configuring file system to have 4KB block size and
mounting it.

> Other than that, this patch looks good to me.
>
> Regards,
> Subhash
>
>> +       else
>> +               blk_queue_logical_block_size(md->queue.queue, 512);
>>        set_capacity(md->disk, size);
>>
>>        if (mmc_host_cmd23(card->host)) {
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index 02914d6..8dcbe995 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -533,6 +533,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8
>> *ext_csd)
>>                } else {
>>                        card->ext_csd.data_tag_unit_size = 0;
>>                }
>> +       } else {
>> +               card->ext_csd.data_sector_size = 512;
>>        }
>>
>>  out:
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/2] MMC-4.5 Power OFF Notify rework

2012-05-14 Thread Saugata Das
On 14 May 2012 16:45, Ulf Hansson  wrote:
> Hi Girish,
>
> Please some comments below.
>
>
> On 05/11/2012 01:44 PM, Subhash Jadavani wrote:
>>
>> Hi Girish,
>>
>> On 5/7/2012 7:11 PM, Girish K S wrote:
>>>
>>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>>> problem
>>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>>> power_mode from mmc_set_ios in different host controller drivers.
>>>
>>> This new patch works around this problem by adding a new host CAP,
>>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>>> host
>>> controller drivers will set this CAP, if they switch off both Vcc and
>>> Vccq
>>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>>
>>> This patch also sends POWER OFF NOTIFY from power management routines
>>> (e.g.
>>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>>> which
>>> does reinitialization of the eMMC on the return path of the power
>>> management
>>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>>> mmc_start_host).
>>>
>>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>>> from
>>> the suspend sequence. If it is sent from shutdown sequence then it is set
>>> to
>>> POWER_OFF_LONG.
>>>
>>> Previuos implementation of PowerOff Notify as a core function is replaced
>>> as
>>> a device's bus operation.
>>>
>>> Signed-off-by: Saugata Das
>>> Signed-off-by: Girish K S
>>>
>>> changes in v3:
>>>       This version addresses the review comments given by Subhash and Ulf
>>> changes in v2:
>>>       This version addresses the changes suggested by Ulf
>>> ---
>>>   drivers/mmc/core/core.c  |   98
>>> +++---
>>>   drivers/mmc/core/core.h  |    1 +
>>>   drivers/mmc/core/mmc.c   |   73 --
>>>   include/linux/mmc/card.h |    8 +++-
>>>   include/linux/mmc/host.h |    9 ++--
>>>   5 files changed, 105 insertions(+), 84 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index ba821fe..3db3b32 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>>> unsigned int drv_type)
>>>       mmc_host_clk_release(host);
>>>   }
>>>
>>> -static void mmc_poweroff_notify(struct mmc_host *host)
>>> -{
>>> -     struct mmc_card *card;
>>> -     unsigned int timeout;
>>> -     unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>>> -     int err = 0;
>>> -
>>> -     card = host->card;
>>> -     mmc_claim_host(host);
>>> -
>>> -     /*
>>> -      * Send power notify command only if card
>>> -      * is mmc and notify state is powered ON
>>> -      */
>>> -     if (card&&   mmc_card_mmc(card)&&
>>> -         (card->poweroff_notify_state == MMC_POWERED_ON)) {
>>> -
>>> -             if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>>> -                     notify_type = EXT_CSD_POWER_OFF_SHORT;
>>> -                     timeout = card->ext_csd.generic_cmd6_time;
>>> -                     card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>>> -             } else {
>>> -                     notify_type = EXT_CSD_POWER_OFF_LONG;
>>> -                     timeout = card->ext_csd.power_off_longtime;
>>> -                     card->poweroff_notify_state = MMC_POWEROFF_LONG;
>>> -             }
>>> -
>>> -             err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> -                              EXT_CSD_POWER_OFF_NOTIFICATION,
>>> -                              notify_type, timeout);
>>> -
>>> -             if (err&&   err != -EBADMSG)
>>> -                     pr_err("Device failed to respond within %d poweroff
>>> "
>>> -                            "time.

Re: [PATCH v3 1/2] MMC-4.5 Power OFF Notify rework

2012-05-14 Thread Saugata Das
On 14 May 2012 14:19, Ulf Hansson  wrote:
> Hi Girish,
>
> This patch is still under discussion.
>
> I would suggest a revert of the old power_off notify patch since it breaks
> suspend for some eMMC devices which supports sleep and which host driver is
> not able to control VCCQ.

The old implementation, wakes up a eMMC-4.41 device from SLEEP and
turns off Vcc. I do not see in the specification that it is wrong (Vcc
can turn OFF at any time). Have you seen any side effect of this patch
?

Note that, for 4.5, the implementation had no problem since power OFF
notify is mandatory feature.

The new patch improves the situation of SLEEP (i.e. no unnecessary
SLEEP/WAKEUP). So, looking forward to your comments for a closure of
this topic.

>
> Then we can continue to look into this patch in more detail. I have some
> additional comments to add soon.
>
> Chris, what do you think?
>
> Kind regards
> Ulf Hansson
>
>
> On 05/11/2012 01:44 PM, Subhash Jadavani wrote:
>>
>> Hi Girish,
>>
>> On 5/7/2012 7:11 PM, Girish K S wrote:
>>>
>>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>>> problem
>>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>>> power_mode from mmc_set_ios in different host controller drivers.
>>>
>>> This new patch works around this problem by adding a new host CAP,
>>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>>> host
>>> controller drivers will set this CAP, if they switch off both Vcc and
>>> Vccq
>>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>>
>>> This patch also sends POWER OFF NOTIFY from power management routines
>>> (e.g.
>>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>>> which
>>> does reinitialization of the eMMC on the return path of the power
>>> management
>>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>>> mmc_start_host).
>>>
>>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>>> from
>>> the suspend sequence. If it is sent from shutdown sequence then it is set
>>> to
>>> POWER_OFF_LONG.
>>>
>>> Previuos implementation of PowerOff Notify as a core function is replaced
>>> as
>>> a device's bus operation.
>>>
>>> Signed-off-by: Saugata Das
>>> Signed-off-by: Girish K S
>>>
>>> changes in v3:
>>>       This version addresses the review comments given by Subhash and Ulf
>>> changes in v2:
>>>       This version addresses the changes suggested by Ulf
>>> ---
>>>   drivers/mmc/core/core.c  |   98
>>> +++---
>>>   drivers/mmc/core/core.h  |    1 +
>>>   drivers/mmc/core/mmc.c   |   73 --
>>>   include/linux/mmc/card.h |    8 +++-
>>>   include/linux/mmc/host.h |    9 ++--
>>>   5 files changed, 105 insertions(+), 84 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index ba821fe..3db3b32 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>>> unsigned int drv_type)
>>>       mmc_host_clk_release(host);
>>>   }
>>>
>>> -static void mmc_poweroff_notify(struct mmc_host *host)
>>> -{
>>> -     struct mmc_card *card;
>>> -     unsigned int timeout;
>>> -     unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>>> -     int err = 0;
>>> -
>>> -     card = host->card;
>>> -     mmc_claim_host(host);
>>> -
>>> -     /*
>>> -      * Send power notify command only if card
>>> -      * is mmc and notify state is powered ON
>>> -      */
>>> -     if (card&&   mmc_card_mmc(card)&&
>>> -         (card->poweroff_notify_state == MMC_POWERED_ON)) {
>>> -
>>> -             if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>>> -                     notify_type = EXT_CSD_POWER_OFF_SHORT;
>>> -                     timeout = card->ext_csd.generic_cmd6_time;
>>>

Re: [PATCH v3 1/2] MMC-4.5 Power OFF Notify rework

2012-05-13 Thread Saugata Das
On 11 May 2012 17:14, Subhash Jadavani  wrote:
> Hi Girish,
>
>
> On 5/7/2012 7:11 PM, Girish K S wrote:
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>> which
>> does reinitialization of the eMMC on the return path of the power
>> management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>> from
>> the suspend sequence. If it is sent from shutdown sequence then it is set
>> to
>> POWER_OFF_LONG.
>>
>> Previuos implementation of PowerOff Notify as a core function is replaced
>> as
>> a device's bus operation.
>>
>> Signed-off-by: Saugata Das
>> Signed-off-by: Girish K S
>>
>> changes in v3:
>>        This version addresses the review comments given by Subhash and Ulf
>> changes in v2:
>>        This version addresses the changes suggested by Ulf
>> ---
>>  drivers/mmc/core/core.c  |   98
>> +++---
>>  drivers/mmc/core/core.h  |    1 +
>>  drivers/mmc/core/mmc.c   |   73 --
>>  include/linux/mmc/card.h |    8 +++-
>>  include/linux/mmc/host.h |    9 ++--
>>  5 files changed, 105 insertions(+), 84 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index ba821fe..3db3b32 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>        mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> -{
>> -       struct mmc_card *card;
>> -       unsigned int timeout;
>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> -
>> -       card = host->card;
>> -       mmc_claim_host(host);
>> -
>> -       /*
>> -        * Send power notify command only if card
>> -        * is mmc and notify state is powered ON
>> -        */
>> -       if (card&&  mmc_card_mmc(card)&&
>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                       timeout = card->ext_csd.generic_cmd6_time;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>> -               } else {
>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                       timeout = card->ext_csd.power_off_longtime;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>> -               }
>> -
>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                                notify_type, timeout);
>> -
>> -               if (err&&  err != -EBADMSG)
>>
>> -                       pr_err("Device failed to respond within %d
>> poweroff "
>> -                              "time. Forcefully powering down the
>> device\n",
>> -                              timeout);
>> -
>> -               /* Set the card state to no notification after the
>> poweroff */
>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>> -       }
>> -       mmc_release_host(host);
>> -}
>> -
>>  /*
>>   * Apply power to the MMC stack.  This is a two-stage process.
&g

[RFC 2/2] [MMC-4.5] [MMC UTIL] Disable emulation

2012-05-09 Thread Saugata Das
From: Saugata Das 

In this patch, we add utility to disable emulation mode in the eMMC-4.5.
This is done to increase the data sector size to 4KB.

Signed-off-by: Saugata Das 
---
 mmc.c  |6 ++
 mmc.h  |2 ++
 mmc_cmds.c |   42 ++
 mmc_cmds.h |1 +
 4 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/mmc.c b/mmc.c
index c27fc24..43b95aa 100644
--- a/mmc.c
+++ b/mmc.c
@@ -65,6 +65,12 @@ static struct Command commands[] = {
"Set the eMMC writeprotect status of .",
  NULL
},
+   { do_disable_emulation, -1,
+ "disable emulation", "\n"
+   "Set the eMMC data sector size to 4KB by disabling emulation 
.",
+ NULL
+   },
+
{ 0, 0, 0, 0 }
 };
 
diff --git a/mmc.h b/mmc.h
index 3af36f1..a2050fa 100644
--- a/mmc.h
+++ b/mmc.h
@@ -35,6 +35,8 @@
 #define EXT_CSD_PART_SWITCH_TIME   199
 #define EXT_CSD_BOOT_CFG   179
 #define EXT_CSD_BOOT_WP173
+#define EXT_CSD_NATIVE_SECTOR_SIZE 63 /* R */
+#define EXT_CSD_NATIVE_SECTOR  62 /* R/W */
 
 /*
  * EXT_CSD field definitions
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 4562cef..2713ccd 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -168,6 +168,48 @@ int do_writeprotect_set(int nargs, char **argv)
return ret;
 }
 
+
+int do_disable_emulation(int nargs, char **argv)
+{
+   __u8 ext_csd[512], native_sector_size;
+   int fd, ret;
+   char *device;
+
+   CHECK(nargs != 2, "Usage: mmc \n", exit(1));
+
+   device = argv[1];
+
+   fd = open(device, O_RDWR);
+   if (fd < 0) {
+   perror("open");
+   exit(1);
+   }
+
+   ret = read_extcsd(fd, ext_csd);
+   if (ret) {
+   fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+   exit(1);
+   }
+
+   native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
+
+   if (native_sector_size) {
+   ret = write_extcsd_value(fd, EXT_CSD_NATIVE_SECTOR, 1);
+
+   if (ret) {
+   fprintf(stderr, "Could not write 0x%02x to "
+   "EXT_CSD[%d] in %s\n",
+   1, EXT_CSD_BOOT_WP, device);
+   exit(1);
+   }
+   } else {
+   printf("MMC does not support 4KB native sector\n");
+   }
+
+   return ret;
+}
+
+
 int do_read_extcsd(int nargs, char **argv)
 {
__u8 ext_csd[512], ext_csd_rev, reg;
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 66e9acb..dd107d5 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv);
 int do_write_extcsd(int nargs, char **argv);
 int do_writeprotect_get(int nargs, char **argv);
 int do_writeprotect_set(int nargs, char **argv);
+int do_disable_emulation(int nargs, char **argv);
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 1/2] [MMC-4.5] Disable emulation

2012-05-09 Thread Saugata Das
From: Saugata Das 

This patch adds the support for large sector size of 4KB by disabling emulation.
This patch passes eMMC DATA_SECTOR_SIZE as the logical block size during
mmc_blk_alloc_req.

In order to use this patch for 4KB sector size, ensure that USE_NATIVE_SECTOR
is enabled, partition table is 4KB sector size aligned and file system block
size is 4KB.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |6 +-
 drivers/mmc/core/mmc.c   |2 ++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a7c75d8..0e54118e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1517,7 +1517,11 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
 "mmcblk%d%s", md->name_idx, subname ? subname : "");
 
-   blk_queue_logical_block_size(md->queue.queue, 512);
+   if (mmc_card_mmc(card))
+   blk_queue_logical_block_size(md->queue.queue,
+   card->ext_csd.data_sector_size);
+   else
+   blk_queue_logical_block_size(md->queue.queue, 512);
set_capacity(md->disk, size);
 
if (mmc_host_cmd23(card->host)) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 02914d6..8dcbe995 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -533,6 +533,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
} else {
card->ext_csd.data_tag_unit_size = 0;
}
+   } else {
+   card->ext_csd.data_sector_size = 512;
}
 
 out:
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] MMC-4.5 Power OFF Notify rework

2012-04-30 Thread Saugata Das
On 30 April 2012 18:39, Subhash Jadavani  wrote:
> On 4/30/2012 11:44 AM, Girish K S wrote:
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>
> What the specification mandates? Does it expect the host to turn off both
> VCC and VCCQ rails after power off notification (short/long)? What if we
> send the power off notification (short/long) but still don't turn off either
> VCCQ or VCC or both?
>

The specification does not say that the power OFF notify has to be
followed by switching off Vcc and Vccq. We however reinitialize eMMC
before using it again.

>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>> which
>> does reinitialization of the eMMC on the return path of the power
>> management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>> from
>> the suspend sequence. If it is sent from shutdown sequence then it is set
>> to
>> POWER_OFF_LONG.
>>
>> Previuos implementation of PowerOff Notify as a core function is replaced
>> as
>> a device's bus operation.
>>
>> Signed-off-by: Saugata Das
>> Signed-off-by: Girish K S
>> ---
>>  drivers/mmc/core/core.c  |   95
>> +++--
>>  drivers/mmc/core/core.h  |    1 +
>>  drivers/mmc/core/mmc.c   |   76 +++--
>>  include/linux/mmc/host.h |    1 +
>>  4 files changed, 98 insertions(+), 75 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index ba821fe..7f5461e 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>        mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> -{
>> -       struct mmc_card *card;
>> -       unsigned int timeout;
>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> -
>> -       card = host->card;
>> -       mmc_claim_host(host);
>> -
>> -       /*
>> -        * Send power notify command only if card
>> -        * is mmc and notify state is powered ON
>> -        */
>> -       if (card&&  mmc_card_mmc(card)&&
>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                       timeout = card->ext_csd.generic_cmd6_time;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>> -               } else {
>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                       timeout = card->ext_csd.power_off_longtime;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>> -               }
>> -
>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                                notify_type, timeout);
>> -
>> -               if (err&&  err != -EBADMSG)
>>
>> -                       pr_err("Device failed to respond within %d
>> poweroff "
>> -                              "time. Forcefully powering down the
>> device\n",
>> -                              timeout);
>> -
>> -               /* Set the card state to no notification after the
>> poweroff */
>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTI

Re: [PATCH V2] MMC-4.5 Power OFF Notify rework

2012-04-30 Thread Saugata Das
On 30 April 2012 14:09, Ulf Hansson  wrote:
> On 04/30/2012 08:14 AM, Girish K S wrote:
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>> which
>> does reinitialization of the eMMC on the return path of the power
>> management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>> from
>> the suspend sequence. If it is sent from shutdown sequence then it is set
>> to
>> POWER_OFF_LONG.
>>
>> Previuos implementation of PowerOff Notify as a core function is replaced
>> as
>> a device's bus operation.
>>
>> Signed-off-by: Saugata Das
>> Signed-off-by: Girish K S
>> ---
>>  drivers/mmc/core/core.c  |   95
>> +++--
>>  drivers/mmc/core/core.h  |    1 +
>>  drivers/mmc/core/mmc.c   |   76 +++--
>>  include/linux/mmc/host.h |    1 +
>>  4 files changed, 98 insertions(+), 75 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index ba821fe..7f5461e 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>        mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> -{
>> -       struct mmc_card *card;
>> -       unsigned int timeout;
>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> -
>> -       card = host->card;
>> -       mmc_claim_host(host);
>> -
>> -       /*
>> -        * Send power notify command only if card
>> -        * is mmc and notify state is powered ON
>> -        */
>> -       if (card&&  mmc_card_mmc(card)&&
>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                       timeout = card->ext_csd.generic_cmd6_time;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>> -               } else {
>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                       timeout = card->ext_csd.power_off_longtime;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>> -               }
>> -
>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                                notify_type, timeout);
>> -
>> -               if (err&&  err != -EBADMSG)
>>
>> -                       pr_err("Device failed to respond within %d
>> poweroff "
>> -                              "time. Forcefully powering down the
>> device\n",
>> -                              timeout);
>> -
>> -               /* Set the card state to no notification after the
>> poweroff */
>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>> -       }
>> -       mmc_release_host(host);
>> -}
>> -
>>  /*
>>   * Apply power to the MMC stack.  This is a two-stage process.
>>   * First, we enable power to the card without the clock running.
>> @@ -1198,30 +1156,12 @@ static void mmc_power_up(struct mmc_host *host)
>>
>>  void mmc_power_off(struct mmc_host *host)
>>  {
>> -       int err = 0;
>>  

Re: [PATCH] MMC-4.5 Power OFF Notify rework

2012-04-27 Thread Saugata Das
On 27 April 2012 13:10, Ulf Hansson  wrote:
> On 04/27/2012 06:40 AM, Girish K S wrote:
>>
>> On 23 April 2012 19:41, Ulf Hansson  wrote:
>>>
>>> Hi Girish,
>>>
>>> Please see some comments below...
>>>
>>>
>>> On 04/20/2012 01:33 PM, Girish K S wrote:
>>>>
>>>>
>>>> On 19 April 2012 18:11, Girish K S
>>>>  wrote:
>>>>>
>>>>>
>>>>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>>>>> problem
>>>>> with the patch comes from the ambiguity on the usage of POWER OFF
>>>>> NOTIFY
>>>>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>>>>> power_mode from mmc_set_ios in different host controller drivers.
>>>>>
>>>>> This new patch works around this problem by adding a new host CAP,
>>>>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>>>>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>>>>> host
>>>>> controller drivers will set this CAP, if they switch off both Vcc and
>>>>> Vccq
>>>>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that
>>>>> there
>>>>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched
>>>>> off.
>>>>>
>>>>> This patch also sends POWER OFF NOTIFY from power management routines
>>>>> (e.g.
>>>>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>>>>> which
>>>>> does reinitialization of the eMMC on the return path of the power
>>>>> management
>>>>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>>>>> mmc_start_host).
>>>>>
>>>>> This patch sets POWER_OFF_NOTIFICATION to POWER_OFF_SHORT if it is sent
>>>>> from
>>>>> the suspend sequence. If it is sent from shutdown sequence then it is
>>>>> set
>>>>> to
>>>>> POWER_OFF_LONG.
>>>>>
>>>>> Previuos implementation of PowerOff Notify as a core function is
>>>>> replaced
>>>>> as
>>>>> a device's bus operation.
>>>
>>>
>>> Great, I like this! :-)
>>>
>>>>>
>>>>> Signed-off-by: Saugata Das
>>>>> Signed-off-by: Girish K S
>>>>> ---
>>>>>  drivers/mmc/core/core.c  |   83
>>>>> ++---
>>>>>  drivers/mmc/core/core.h  |    1 +
>>>>>  drivers/mmc/core/mmc.c   |   75
>>>>> +++---
>>>>>  include/linux/mmc/host.h |    1 +
>>>>>  4 files changed, 84 insertions(+), 76 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>>> index e541efb..4b8b2c1 100644
>>>>> --- a/drivers/mmc/core/core.c
>>>>> +++ b/drivers/mmc/core/core.c
>>>>> @@ -1100,48 +1100,6 @@ void mmc_set_driver_type(struct mmc_host *host,
>>>>> unsigned int drv_type)
>>>>>        mmc_host_clk_release(host);
>>>>>  }
>>>>>
>>>>> -static void mmc_poweroff_notify(struct mmc_host *host)
>>>>> -{
>>>>> -       struct mmc_card *card;
>>>>> -       unsigned int timeout;
>>>>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>>>>> -       int err = 0;
>>>>> -
>>>>> -       card = host->card;
>>>>> -       mmc_claim_host(host);
>>>>> -
>>>>> -       /*
>>>>> -        * Send power notify command only if card
>>>>> -        * is mmc and notify state is powered ON
>>>>> -        */
>>>>> -       if (card&&   mmc_card_mmc(card)&&
>>>>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>>>>> -
>>>>> -               if (host->power_notify_type ==
>>>>> MMC_HOST_PW_NOTIFY_SHORT)
>>>>> {
>>>>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>>>>> -                       timeout = card->ext_csd.generic_cmd6_time;
>>>>> -                       card->poweroff_notify_state 

Re: [RFC] MMC-4.5 Power OFF Notify rework

2012-04-05 Thread Saugata Das
On 4 April 2012 17:03, Ulf Hansson  wrote:
> On 03/30/2012 12:02 PM, Girish K S wrote:
>>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current
>> problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that
>> host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines
>> (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host),
>> which
>> does reinitialization of the eMMC on the return path of the power
>> management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> Signed-off-by: Saugata Das
>> Signed-off-by: Girish K S
>> ---
>>  drivers/mmc/core/core.c  |   36 ++--
>>  drivers/mmc/core/core.h  |    1 +
>>  drivers/mmc/core/mmc.c   |   20 +---
>>  include/linux/mmc/host.h |    1 +
>>  4 files changed, 29 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index 14f262e..dc85ee1 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1096,12 +1096,12 @@ void mmc_set_driver_type(struct mmc_host *host,
>> unsigned int drv_type)
>>        mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> +int mmc_poweroff_notify(struct mmc_host *host)
>
>
> A more generic comment; why is not this function implemented as a bus_ops
> function, similar how sleep for mmc is done? That would be more preferred I
> think.
>

I have nothing for or against the idea. We just wanted to limit the
changes in the patch. In this patch lets focus on the functional
aspects of the power off notify and we can work on moving this
function to bus_ops in a separate patch later.

>
>>  {
>>        struct mmc_card *card;
>>        unsigned int timeout;
>>        unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> +       int err = -EINVAL;
>>
>>        card = host->card;
>>        mmc_claim_host(host);
>> @@ -1136,6 +1136,7 @@ static void mmc_poweroff_notify(struct mmc_host
>> *host)
>>                card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>>        }
>>        mmc_release_host(host);
>> +       return err;
>>  }
>>
>>  /*
>> @@ -1194,30 +1195,12 @@ static void mmc_power_up(struct mmc_host *host)
>>
>>  void mmc_power_off(struct mmc_host *host)
>>  {
>> -       int err = 0;
>>        mmc_host_clk_hold(host);
>>
>>        host->ios.clock = 0;
>>        host->ios.vdd = 0;
>>
>>        /*
>> -        * For eMMC 4.5 device send AWAKE command before
>> -        * POWER_OFF_NOTIFY command, because in sleep state
>> -        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
>> -        */
>> -       if (host->card&&  mmc_card_is_sleep(host->card)&&
>> -           host->bus_ops->resume) {
>> -               err = host->bus_ops->resume(host);
>> -
>> -               if (!err)
>> -                       mmc_poweroff_notify(host);
>> -               else
>> -                       pr_warning("%s: error %d during resume "
>> -                                  "(continue with poweroff sequence)\n",
>> -                                  mmc_hostname(host), err);
>> -       }
>> -
>> -       /*
>>         * Reset ocr mask to be the highest possible voltage supported for
>>         * this mmc host. This value will be used at next power up.
>>         */
>> @@ -2076,6 +2059,7 @@ void mmc_stop_host(struct mmc_host *host)
>>        host->pm_flags = 0;
>>
>>        mmc_bus_get(host);
>> +       mmc_poweroff_notify(host);
>
>
> We must not do mmc_poweroff_notify, without knowing we have a card attached
> through the bus_ops.
>
>>        if (host

Re: [PATCH v1 1/1] mmc: core: fix power class selection

2012-04-03 Thread Saugata Das
On 3 April 2012 22:14, Subhash Jadavani  wrote:
>
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> ow...@vger.kernel.org] On Behalf Of Saugata Das
>> Sent: Tuesday, April 03, 2012 9:48 PM
>> To: Subhash Jadavani
>> Cc: linux-mmc@vger.kernel.org; linux-arm-...@vger.kernel.org;
>> girish.shivananja...@linaro.org
>> Subject: Re: [PATCH v1 1/1] mmc: core: fix power class selection
>>
>> On 3 April 2012 21:20, Subhash Jadavani  wrote:
>> >
>> >
>> >> -Original Message-
>> >> From: Saugata Das [mailto:saugata@linaro.org]
>> >> Sent: Tuesday, April 03, 2012 8:55 PM
>> >> To: Subhash Jadavani
>> >> Cc: linux-mmc@vger.kernel.org; linux-arm-...@vger.kernel.org;
>> >> girish.shivananja...@linaro.org
>> >> Subject: Re: [PATCH v1 1/1] mmc: core: fix power class selection
>> >>
>> >> On 3 April 2012 12:25, Subhash Jadavani 
>> wrote:
>> >> > mmc_select_powerclass() function returns error if eMMC VDD level
>> >> > supported by host is between 2.7v to 3.2v.
>> >> >
>> >> > According to eMMC specification, valid voltage for high voltage
>> >> > cards is 2.7v to 3.6v. This patch ensures that 2.7v to 3.6v VDD
>> >> > range is treated as valid range.
>> >> >
>> >> > Also, failure to set the power class shouldn't be treated as fatal
>> >> > error because even if setting the power class fails, card can still
>> >> > work in default power class.
>> >> > If mmc_select_powerclass() returns error, just print the warning
>> >> > message and go ahead with rest of the card initialization.
>> >> >
>> >>
>> >> Have you checked why mmc_select_powerclass returned error ? Today,
>> in
>> >> the mmc_select_powerclass, it is just setting the value of power
>> >> class,
>> > which
>> >> the eMMC expects. So, it should not fail.
>> >>
>> >> Another point is that, today mmc_select_powerclass is assuming that
>> >> host can support the maximum possible power classes and it does not
>> >> check host controllers capability in driving higher current (mA). But
>> >> I think in
>> > future we
>> >> need to add this check for host controller ability and return error
>> >> from mmc_select_powerclass so that mmc_init_card can choose the next
>> >> speed
>> >
>> > Agreed with this point.
>> >
>> >> mode. From that perspective, the approach to ignore the error return
>> >> from mmc_select_powerclass looks wrong.
>> >
>> > My patch was just intended to fix the issue existing power class
>> > implementation. As commit text says:
>> >        - don't consider 2.7v to 3.2v as invalid range
>> >        - We are already ignoring the error returned by
>> > mmc_set_power_class() function for DS/HS/DDR cards. So this patch has
>> > extended that to HS200 cards.
>> >
>> > So as far as this patch is concerned, I don't see anything wrong here.
>> >
>> > As you have mentioned, currently we are not taking the host controller
>> > capability into account (as it doesn't exist as of now) so we should
>> > not see
>> > mmc_select_powerclass() fail any time.
>>
>> This is actually the main concern. The fail of mmc_select_powerclass is
>> something to be checked and not ignored since it should not fail under the
>> current implementation.
>
> Yes, this makes sense. With current implementation, mmc_select_powerclass()
> should never really fail which means failure should be treated as fatal and
> we should really skip the card initialization.
> This patch is already pushed to mmc-next. So I will post another patch (by
> next week as I will be on vacation in this week) to skip the card
> initialization if mmc_select_powerclass fails.
>
> Is this ok?

It is OK. Thanks,

>
> Regards,
> Subhash
>
>>
>>
>> > But yes, next thing should be to take into account the host current
>> > sourcing capability before deciding which bus speed mode to choose.
>> > But that may be a big change and should be as separate patch. Girish
>> > had already posted one patch for this which needs to be extended to
>> achieve this.
>> >
>> > Regards,
>> > Subhash
>> >
>> >>
>> >>
>> >> > Signed-

Re: [PATCH v1 1/1] mmc: core: fix power class selection

2012-04-03 Thread Saugata Das
On 3 April 2012 21:20, Subhash Jadavani  wrote:
>
>
>> -Original Message-----
>> From: Saugata Das [mailto:saugata@linaro.org]
>> Sent: Tuesday, April 03, 2012 8:55 PM
>> To: Subhash Jadavani
>> Cc: linux-mmc@vger.kernel.org; linux-arm-...@vger.kernel.org;
>> girish.shivananja...@linaro.org
>> Subject: Re: [PATCH v1 1/1] mmc: core: fix power class selection
>>
>> On 3 April 2012 12:25, Subhash Jadavani  wrote:
>> > mmc_select_powerclass() function returns error if eMMC VDD level
>> > supported by host is between 2.7v to 3.2v.
>> >
>> > According to eMMC specification, valid voltage for high voltage cards
>> > is 2.7v to 3.6v. This patch ensures that 2.7v to 3.6v VDD range is
>> > treated as valid range.
>> >
>> > Also, failure to set the power class shouldn't be treated as fatal
>> > error because even if setting the power class fails, card can still
>> > work in default power class.
>> > If mmc_select_powerclass() returns error, just print the warning
>> > message and go ahead with rest of the card initialization.
>> >
>>
>> Have you checked why mmc_select_powerclass returned error ? Today, in
>> the mmc_select_powerclass, it is just setting the value of power class,
> which
>> the eMMC expects. So, it should not fail.
>>
>> Another point is that, today mmc_select_powerclass is assuming that host
>> can support the maximum possible power classes and it does not check host
>> controllers capability in driving higher current (mA). But I think in
> future we
>> need to add this check for host controller ability and return error from
>> mmc_select_powerclass so that mmc_init_card can choose the next speed
>
> Agreed with this point.
>
>> mode. From that perspective, the approach to ignore the error return from
>> mmc_select_powerclass looks wrong.
>
> My patch was just intended to fix the issue existing power class
> implementation. As commit text says:
>        - don't consider 2.7v to 3.2v as invalid range
>        - We are already ignoring the error returned by
> mmc_set_power_class() function for DS/HS/DDR cards. So this patch has
> extended that to HS200 cards.
>
> So as far as this patch is concerned, I don't see anything wrong here.
>
> As you have mentioned, currently we are not taking the host controller
> capability into account (as it doesn't exist as of now) so we should not see
> mmc_select_powerclass() fail any time.

This is actually the main concern. The fail of mmc_select_powerclass
is something to be checked and not ignored since it should not fail
under the current implementation.


> But yes, next thing should be to take into account the host current sourcing
> capability before deciding which bus speed mode to choose. But that may be a
> big change and should be as separate patch. Girish had already posted one
> patch for this which needs to be extended to achieve this.
>
> Regards,
> Subhash
>
>>
>>
>> > Signed-off-by: Subhash Jadavani 
>> > ---
>> >  drivers/mmc/core/mmc.c |   30 +-
>> >  1 files changed, 17 insertions(+), 13 deletions(-)
>> >
>> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index
>> > 02914d6..54df5ad 100644
>> > --- a/drivers/mmc/core/mmc.c
>> > +++ b/drivers/mmc/core/mmc.c
>> > @@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card
>> > *card,
>> >                else if (host->ios.clock <= 2)
>> >                        index = EXT_CSD_PWR_CL_200_195;
>> >                break;
>> > +       case MMC_VDD_27_28:
>> > +       case MMC_VDD_28_29:
>> > +       case MMC_VDD_29_30:
>> > +       case MMC_VDD_30_31:
>> > +       case MMC_VDD_31_32:
>> >        case MMC_VDD_32_33:
>> >        case MMC_VDD_33_34:
>> >        case MMC_VDD_34_35:
>> > @@ -,11 +1116,10 @@ static int mmc_init_card(struct mmc_host
>> > *host, u32 ocr,
>> >                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
>> >                                EXT_CSD_BUS_WIDTH_8 :
>> > EXT_CSD_BUS_WIDTH_4;
>> >                err = mmc_select_powerclass(card, ext_csd_bits,
>> > ext_csd);
>> > -               if (err) {
>> > -                       pr_err("%s: power class selection to bus width
>> > %d failed\n",
>> > -                               mmc_hostname(card->host), 1 <<
>> > bus_width);
>> > -      

Re: [PATCH v1 1/1] mmc: core: fix power class selection

2012-04-03 Thread Saugata Das
On 3 April 2012 12:25, Subhash Jadavani  wrote:
> mmc_select_powerclass() function returns error if eMMC
> VDD level supported by host is between 2.7v to 3.2v.
>
> According to eMMC specification, valid voltage for high
> voltage cards is 2.7v to 3.6v. This patch ensures that
> 2.7v to 3.6v VDD range is treated as valid range.
>
> Also, failure to set the power class shouldn't be treated
> as fatal error because even if setting the power class
> fails, card can still work in default power class.
> If mmc_select_powerclass() returns error, just print
> the warning message and go ahead with rest of the card
> initialization.
>

Have you checked why mmc_select_powerclass returned error ? Today, in
the mmc_select_powerclass, it is just setting the value of power
class, which the eMMC expects. So, it should not fail.

Another point is that, today mmc_select_powerclass is assuming that
host can support the maximum possible power classes and it does not
check host controllers capability in driving higher current (mA). But
I think in future we need to add this check for host controller
ability and return error from mmc_select_powerclass so that
mmc_init_card can choose the next speed mode. From that perspective,
the approach to ignore the error return from mmc_select_powerclass
looks wrong.


> Signed-off-by: Subhash Jadavani 
> ---
>  drivers/mmc/core/mmc.c |   30 +-
>  1 files changed, 17 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 02914d6..54df5ad 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card,
>                else if (host->ios.clock <= 2)
>                        index = EXT_CSD_PWR_CL_200_195;
>                break;
> +       case MMC_VDD_27_28:
> +       case MMC_VDD_28_29:
> +       case MMC_VDD_29_30:
> +       case MMC_VDD_30_31:
> +       case MMC_VDD_31_32:
>        case MMC_VDD_32_33:
>        case MMC_VDD_33_34:
>        case MMC_VDD_34_35:
> @@ -,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 
> ocr,
>                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
>                                EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
>                err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
> -               if (err) {
> -                       pr_err("%s: power class selection to bus width %d 
> failed\n",
> -                               mmc_hostname(card->host), 1 << bus_width);
> -                       goto err;
> -               }
> +               if (err)
> +                       pr_warning("%s: power class selection to bus width %d"
> +                                  " failed\n", mmc_hostname(card->host),
> +                                  1 << bus_width);
>        }
>
>        /*
> @@ -1147,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 
> ocr,
>                        err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
>                                                    ext_csd);
>                        if (err)
> -                               pr_err("%s: power class selection to "
> -                                      "bus width %d failed\n",
> -                                      mmc_hostname(card->host),
> -                                      1 << bus_width);
> +                               pr_warning("%s: power class selection to "
> +                                          "bus width %d failed\n",
> +                                          mmc_hostname(card->host),
> +                                          1 << bus_width);
>
>                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>                                         EXT_CSD_BUS_WIDTH,
> @@ -1178,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 
> ocr,
>                        err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
>                                                    ext_csd);
>                        if (err)
> -                               pr_err("%s: power class selection to "
> -                                      "bus width %d ddr %d failed\n",
> -                                      mmc_hostname(card->host),
> -                                      1 << bus_width, ddr);
> +                               pr_warning("%s: power class selection to "
> +                                          "bus width %d ddr %d failed\n",
> +                                          mmc_hostname(card->host),
> +                                          1 << bus_width, ddr);
>
>                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>                                         EXT_CSD_BUS_WIDTH,
> --
> 1.7.1.1
>
> --
> Sent by a consultant of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
> --
> To unsubscribe from this l

Re: [PATCH V2] mmc: core: Add host capability check for power class

2012-04-03 Thread Saugata Das
On 2 April 2012 16:24, Subhash Jadavani  wrote:
>
>
>> -Original Message-----
>> From: Saugata Das [mailto:saugata@linaro.org]
>> Sent: Monday, April 02, 2012 1:20 PM
>> To: Subhash Jadavani
>> Cc: Girish K S; linux-mmc@vger.kernel.org; patc...@linaro.org; linux-
>> samsung-...@vger.kernel.org; Chris Ball
>> Subject: Re: [PATCH V2] mmc: core: Add host capability check for power
> class
>>
>> On 28 March 2012 16:39, Subhash Jadavani 
>> wrote:
>> >
>> >
>> >> -Original Message-
>> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> >> ow...@vger.kernel.org] On Behalf Of Saugata Das
>> >> Sent: Thursday, December 15, 2011 6:35 PM
>> >> To: Girish K S
>> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>> >> s...@vger.kernel.org; subha...@codeaurora.org; Chris Ball
>> >> Subject: Re: [PATCH V2] mmc: core: Add host capability check for
>> >> power
>> > class
>> >>
>> >> On 15 December 2011 16:22, Girish K S
>> >> 
>> >> wrote:
>> >> > On 15 December 2011 15:34, Saugata Das 
>> wrote:
>> >> >> On 15 December 2011 09:28, Girish K S
>> >> >> 
>> >> wrote:
>> >> >>> This patch adds a check whether the host supports maximum current
>> >> >>> value obtained from the device's extended csd register for a
>> >> >>> selected interface voltage and frequency.
>> >> >>>
>> >> >>> cc: Chris Ball 
>> >> >>> Signed-off-by: Girish K S 
>> >> >>> ---
>> >> >>> Changes in v2:
>> >> >>>        deleted a unnecessary if else condition identified by
>> >> >>> subhash J Changes in v1:
>> >> >>>       reduced the number of comparisons as per Hein's suggestion
>> >> >>>
>> >> >>>  drivers/mmc/core/mmc.c   |   19 +++
>> >> >>>  include/linux/mmc/card.h |    4 
>> >> >>>  2 files changed, 23 insertions(+), 0 deletions(-)
>> >> >>>
>> >> >>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> >> >>> index
>> >> >>> 006e932..b9ef777 100644
>> >> >>> --- a/drivers/mmc/core/mmc.c
>> >> >>> +++ b/drivers/mmc/core/mmc.c
>> >> >>> @@ -688,6 +688,25 @@ static int mmc_select_powerclass(struct
>> >> >>> mmc_card *card,
>> >> >>>                pwrclass_val = (pwrclass_val &
>> >> >>> EXT_CSD_PWR_CL_4BIT_MASK) >>
>> >> >>>                                EXT_CSD_PWR_CL_4BIT_SHIFT;
>> >> >>>
>> >> >>> +       if (pwrclass_val >= MMC_MAX_CURRENT_800)
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_800;
>> >> >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_600)
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>> >> >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_400)
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>> >> >>> +       else
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>> >> >>> +
>> >> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_800) &&
>> >> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_800))
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>> >> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_600) &&
>> >> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_600))
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>> >> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_400) &&
>> >> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_400))
>> >> >>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>> >> >>> +
>> >> >>>        /* If the power class is different from the default value
>> >> >>> */
>> >> >>>        if (pwrclass_val > 0) {
>> >> >>>                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>

Re: [RFC] MMC-4.5 Power OFF Notify rework

2012-04-03 Thread Saugata Das
On 2 April 2012 21:26, Linus Walleij  wrote:
> On Mon, Apr 2, 2012 at 10:47 AM, Saugata Das  wrote:
>
>>>> +       host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>>>
>>> This looks new, can you explain in the code as comments
>>> or in the commit message when SHORT and LONG notifications are
>>> used and why?
>>>
>>
>> The mmc_poweroff_notify with MMC_HOST_PW_NOTIFY_LONG will take longer
>> time  to complete than MMC_HOST_PW_NOTIFY_SHORT. So, the idea is that
>> if we use mmc_poweroff_notify on suspend path, then we should use
>> MMC_HOST_PW_NOTIFY_SHORT and if we use mmc_poweroff_notify from the
>> shutdown path, then we should use MMC_HOST_PW_NOTIFY_LONG.
>>
>> We will add this in the description.
>
> OK sounds good.
>
>>>> @@ -1338,12 +1338,18 @@ static int mmc_suspend(struct mmc_host *host)
>>>>        BUG_ON(!host->card);
>>>>
>>>>        mmc_claim_host(host);
>>>> -       if (mmc_card_can_sleep(host)) {
>>>> -               err = mmc_card_sleep(host);
>>>> +       if (host->caps2 & MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND) {
>>>> +               err = mmc_poweroff_notify(host);
>>>>                if (!err)
>>>> -                       mmc_card_set_sleep(host->card);
>>>> -       } else if (!mmc_host_is_spi(host))
>>>> +                       goto out;
>>>> +       }
>>>> +
>>>> +       if (mmc_card_can_sleep(host))
>>>> +               err = mmc_card_sleep(host);
>>>> +       else if (!mmc_host_is_spi(host))
>>>>                mmc_deselect_cards(host);
>>>
>>> Are you sure you should not deselect the card on an SPI host also if
>>> you power off? (I'm just confused, better to ask...)
>>>
>>
>> eMMC does not support SPI mode. So, the POWER OFF NOTIFY, which is an
>> eMMC feature, can not be used on SPI mode. The above code (which you
>> are referring) puts the eMMC to low power "standby" state with
>> mmc_deselect_cards if sleep is not allowed. This logic has not been
>> modified by the POWER OFF NOTIFY patch.
>
> OK I would add a small comment above the else if (!mmc_host_is_spi(host))
> such as /* SPI mode is only used external cards */ or so, it helsps when
> reading the code.
>

I understand but power off notify patch did not introduce this. May
be, we can add this comment in a different patch.

If no other comments, then we will resubmit this patch with
modification of the description.


> Yours,
> Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] MMC-4.5 Power OFF Notify rework

2012-04-02 Thread Saugata Das
On 30 March 2012 21:19, Linus Walleij  wrote:
> On Fri, Mar 30, 2012 at 12:02 PM, Girish K S
>  wrote:
>
>> This is a rework of the existing POWER OFF NOTIFY patch. The current problem
>> with the patch comes from the ambiguity on the usage of POWER OFF NOTIFY
>> together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
>> power_mode from mmc_set_ios in different host controller drivers.
>>
>> This new patch works around this problem by adding a new host CAP,
>> MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
>> POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that host
>> controller drivers will set this CAP, if they switch off both Vcc and Vccq
>> from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
>> is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.
>>
>> This patch also sends POWER OFF NOTIFY from power management routines (e.g.
>> mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host), which
>> does reinitialization of the eMMC on the return path of the power management
>> routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
>> mmc_start_host).
>>
>> Signed-off-by: Saugata Das 
>> Signed-off-by: Girish K S 
>
> Overall this looks good!
>
> I think it may be possible to split the patch.
> First a patch that moves mmc_card_set_sleep() and mmc_card_clr_sleep()
> into mmc_card_sleep() and mmc_card_awake(), which is a good
> refactoring in its own right. Then a patch doing the rest of the changes.
>
> (But that's no big deal to me if Chris is OK with this.)
>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> +int mmc_poweroff_notify(struct mmc_host *host)
>
> So now this function will return an errorcode if notification fails,
> maybe add some kerneldoc...
>
>> @@ -2112,7 +2096,8 @@ int mmc_power_save_host(struct mmc_host *host)
>>
>>        if (host->bus_ops->power_save)
>>                ret = host->bus_ops->power_save(host);
>> -
>> +       host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>> +       mmc_poweroff_notify(host);
>
> So no risk in ignoring poweroff notification failure here I guess..
> (Just thinking aloud.)
>
>> @@ -2135,7 +2120,7 @@ int mmc_power_restore_host(struct mmc_host *host)
>>                mmc_bus_put(host);
>>                return -EINVAL;
>>        }
>> -
>> +       host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>
> This looks new, can you explain in the code as comments
> or in the commit message when SHORT and LONG notifications are
> used and why?
>

The mmc_poweroff_notify with MMC_HOST_PW_NOTIFY_LONG will take longer
time  to complete than MMC_HOST_PW_NOTIFY_SHORT. So, the idea is that
if we use mmc_poweroff_notify on suspend path, then we should use
MMC_HOST_PW_NOTIFY_SHORT and if we use mmc_poweroff_notify from the
shutdown path, then we should use MMC_HOST_PW_NOTIFY_LONG.

We will add this in the description.

>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index 02914d6..885ad61 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -1338,12 +1338,18 @@ static int mmc_suspend(struct mmc_host *host)
>>        BUG_ON(!host->card);
>>
>>        mmc_claim_host(host);
>> -       if (mmc_card_can_sleep(host)) {
>> -               err = mmc_card_sleep(host);
>> +       if (host->caps2 & MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND) {
>> +               err = mmc_poweroff_notify(host);
>>                if (!err)
>> -                       mmc_card_set_sleep(host->card);
>> -       } else if (!mmc_host_is_spi(host))
>> +                       goto out;
>> +       }
>> +
>> +       if (mmc_card_can_sleep(host))
>> +               err = mmc_card_sleep(host);
>> +       else if (!mmc_host_is_spi(host))
>>                mmc_deselect_cards(host);
>
> Are you sure you should not deselect the card on an SPI host also if
> you power off? (I'm just confused, better to ask...)
>

eMMC does not support SPI mode. So, the POWER OFF NOTIFY, which is an
eMMC feature, can not be used on SPI mode. The above code (which you
are referring) puts the eMMC to low power "standby" state with
mmc_deselect_cards if sleep is not allowed. This logic has not been
modified by the POWER OFF NOTIFY patch.

>> +
>> +out:
>
> So if I understand correctly we power off if possible, else we
> set the card to sleep. (Looks good.)
>
>>        mmc_claim_host(host);
>> -       if (mmc_card_is_sleep(host->card)) {
>> +       if (mmc_card_is_sleep(host->card))
>>                err = mmc_card_awake(host);
>> -               mmc_card_clr_sleep(host->card);
>> -       } else
>> +       else
>>                err = mmc_init_card(host, host->ocr, host->card);
>
> So a powered-off card will be reinitialized here, nice!
>
> Yours,
> Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] mmc: core: Add host capability check for power class

2012-04-02 Thread Saugata Das
On 28 March 2012 16:39, Subhash Jadavani  wrote:
>
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> ow...@vger.kernel.org] On Behalf Of Saugata Das
>> Sent: Thursday, December 15, 2011 6:35 PM
>> To: Girish K S
>> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>> s...@vger.kernel.org; subha...@codeaurora.org; Chris Ball
>> Subject: Re: [PATCH V2] mmc: core: Add host capability check for power
> class
>>
>> On 15 December 2011 16:22, Girish K S 
>> wrote:
>> > On 15 December 2011 15:34, Saugata Das  wrote:
>> >> On 15 December 2011 09:28, Girish K S 
>> wrote:
>> >>> This patch adds a check whether the host supports maximum current
>> >>> value obtained from the device's extended csd register for a
>> >>> selected interface voltage and frequency.
>> >>>
>> >>> cc: Chris Ball 
>> >>> Signed-off-by: Girish K S 
>> >>> ---
>> >>> Changes in v2:
>> >>>        deleted a unnecessary if else condition identified by subhash
>> >>> J Changes in v1:
>> >>>       reduced the number of comparisons as per Hein's suggestion
>> >>>
>> >>>  drivers/mmc/core/mmc.c   |   19 +++
>> >>>  include/linux/mmc/card.h |    4 
>> >>>  2 files changed, 23 insertions(+), 0 deletions(-)
>> >>>
>> >>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index
>> >>> 006e932..b9ef777 100644
>> >>> --- a/drivers/mmc/core/mmc.c
>> >>> +++ b/drivers/mmc/core/mmc.c
>> >>> @@ -688,6 +688,25 @@ static int mmc_select_powerclass(struct
>> >>> mmc_card *card,
>> >>>                pwrclass_val = (pwrclass_val &
>> >>> EXT_CSD_PWR_CL_4BIT_MASK) >>
>> >>>                                EXT_CSD_PWR_CL_4BIT_SHIFT;
>> >>>
>> >>> +       if (pwrclass_val >= MMC_MAX_CURRENT_800)
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_800;
>> >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_600)
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>> >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_400)
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>> >>> +       else
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>> >>> +
>> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_800) &&
>> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_800))
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_600) &&
>> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_600))
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>> >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_400) &&
>> >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_400))
>> >>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>> >>> +
>> >>>        /* If the power class is different from the default value */
>> >>>        if (pwrclass_val > 0) {
>> >>>                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> >>
>> >> It is not allowed to set the POWER_CLASS with any value other than
>> >> what is mentioned in the PWR_CL_ff_vvv or PWR_CL_DDR_ff_vvv  for
>> the
>> >> corresponding frequency, voltage. That is, if PWR_CL_200_195 is 14
>> >> and we want to operate at HS200 then the only value allowed for
>> >> POWER_CLASS is 14. So, we need to check the PWR_CL numbers and
>> choose
>> >> the operating mode (HS200/DDR50/..) based on the platform capability
>> >> to support the current consumption and set the corresponding
>> >> POWER_CLASS value.
>> >>
>> >> Please refer to section 6.6.5 of the 4.5 spec.
>> >
>> > The upstreamed code reads the extended csd value based on the already
>> > set voltage level and frequency of host. So it will get the required
>> > power class value which can be set directly. Is my understanding
>> > correct?
>> >
>>
>> It is not enough to just check the voltage level and frequency.
>> Consider this example, host has capability to support
>> M

[RFC] MMC-4.5 Power OFF Notify rework

2012-03-30 Thread Saugata Das
From: Saugata Das 

This is a rework of the existing POWER OFF NOTIFY patch. The problem with
the existing patch comes from the ambiguity on the usage of POWER OFF NOTIFY
together with SLEEP and misunderstanding on the usage of MMC_POWER_OFF
power_mode from mmc_set_ios in different host controller drivers.

This new patch works around this problem by adding a new host CAP,
MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND, which when set sends a
POWER OFF NOTIFY from mmc_suspend instead of SLEEP. It is expected that host
controller drivers will set this CAP, if they switch off both Vcc and Vccq
from MMC_POWER_OFF condition within mmc_set_ios. However, note that there
is no harm in sending MMC_POWER_NOTIFY even if Vccq is not switched off.

This patch also sends POWER OFF NOTIFY from power management routines (e.g.
mmc_power_save_host, mmc_pm_notify/PM_SUSPEND_PREPARE, mmc_stop_host), which
does reinitialization of the eMMC on the return path of the power management
routines (e.g. mmc_power_restore_host, mmc_pm_notify/PM_POST_RESTORE,
mmc_start_host).

Signed-off-by: Saugata Das 
Signed-off-by: Girish K S 
---
 drivers/mmc/core/core.c  |   36 ++--
 drivers/mmc/core/core.h  |1 +
 drivers/mmc/core/mmc.c   |   18 +++---
 include/linux/mmc/host.h |1 +
 4 files changed, 27 insertions(+), 29 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 14f262e..dc85ee1 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1096,12 +1096,12 @@ void mmc_set_driver_type(struct mmc_host *host, 
unsigned int drv_type)
mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
+int mmc_poweroff_notify(struct mmc_host *host)
 {
struct mmc_card *card;
unsigned int timeout;
unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-   int err = 0;
+   int err = -EINVAL;
 
card = host->card;
mmc_claim_host(host);
@@ -1136,6 +1136,7 @@ static void mmc_poweroff_notify(struct mmc_host *host)
card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
}
mmc_release_host(host);
+   return err;
 }
 
 /*
@@ -1194,30 +1195,12 @@ static void mmc_power_up(struct mmc_host *host)
 
 void mmc_power_off(struct mmc_host *host)
 {
-   int err = 0;
mmc_host_clk_hold(host);
 
host->ios.clock = 0;
host->ios.vdd = 0;
 
/*
-* For eMMC 4.5 device send AWAKE command before
-* POWER_OFF_NOTIFY command, because in sleep state
-* eMMC 4.5 devices respond to only RESET and AWAKE cmd
-*/
-   if (host->card && mmc_card_is_sleep(host->card) &&
-   host->bus_ops->resume) {
-   err = host->bus_ops->resume(host);
-
-   if (!err)
-   mmc_poweroff_notify(host);
-   else
-   pr_warning("%s: error %d during resume "
-  "(continue with poweroff sequence)\n",
-  mmc_hostname(host), err);
-   }
-
-   /*
 * Reset ocr mask to be the highest possible voltage supported for
 * this mmc host. This value will be used at next power up.
 */
@@ -2076,6 +2059,7 @@ void mmc_stop_host(struct mmc_host *host)
host->pm_flags = 0;
 
mmc_bus_get(host);
+   mmc_poweroff_notify(host);
if (host->bus_ops && !host->bus_dead) {
/* Calling bus_ops->remove() with a claimed host can deadlock */
if (host->bus_ops->remove)
@@ -2112,7 +2096,8 @@ int mmc_power_save_host(struct mmc_host *host)
 
if (host->bus_ops->power_save)
ret = host->bus_ops->power_save(host);
-
+   host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
+   mmc_poweroff_notify(host);
mmc_bus_put(host);
 
mmc_power_off(host);
@@ -2135,7 +2120,7 @@ int mmc_power_restore_host(struct mmc_host *host)
mmc_bus_put(host);
return -EINVAL;
}
-
+   host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
mmc_power_up(host);
ret = host->bus_ops->power_restore(host);
 
@@ -2157,6 +2142,9 @@ int mmc_card_awake(struct mmc_host *host)
if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
err = host->bus_ops->awake(host);
 
+   if (!err)
+   mmc_card_clr_sleep(host->card);
+
mmc_bus_put(host);
 
return err;
@@ -2175,6 +2163,9 @@ int mmc_card_sleep(struct mmc_host *host)
if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
err = host->bus_ops->sleep(host);
 
+   if (!err)
+   mmc_card_set_sleep(host->card);
+
mmc_bus_put(host);

Re: [PATCH] mmc: core: Fix PowerOff Notify suspend/resume

2012-03-15 Thread Saugata Das
On 16 March 2012 09:19, Girish K S  wrote:
> On 14 March 2012 20:53, Ulf Hansson  wrote:
>> Hi Girish and Chris,
>>
>> I noticed that this has been pushed for 3.3, I think we need to make a
>> revert of it asap if possible.
>>
>> I were unfortunately not able to review this patch earlier but it has issues
>> I believe. It will break suspend/resume for eMMC devices supporting the
>> SLEEP command and not the "poweroff notify" from eMMC 4.5.
>
> By break do you mean compilation break or system crash. can you please
> post the log that caused the break.
> I re checked it on eMMC 4.5, 4.41, high speed mmc card and normal mmc
> card. I can compile successfully and
> could test the suspend/ resume functionality without carsh.
> If you provide the log, i can check more.
>
>>
>> Please see my comments below.
>>
>>
>> On 01/31/2012 11:14 AM, Girish K S wrote:
>>>
>>> Modified the mmc_poweroff to resume before sending the
>>> poweroff notification command. In sleep mode only AWAKE
>>> and RESET commands are allowed, so before sending the
>>> poweroff notification command resume from sleep mode and
>>> then send the notification command.
>>>
>>> POwerOff Notify is tested on a Synopsis Designware Host
>>> Controller(eMMC 4.5). The suspend to RAM and resume works fine.
>>>
>>> This patch is successfully applied on the Chris's mmc-next
>>> branch
>>>
>>> cc: Chris Ball
>>> Signed-off-by: Girish K S
>>> Tested-by: Girish K S
>>> ---
>>>  drivers/mmc/core/core.c  |   28 
>>>  drivers/mmc/core/mmc.c   |   17 -
>>>  include/linux/mmc/card.h |    4 
>>>  3 files changed, 36 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index bec0bf2..14ec575 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1239,7 +1239,8 @@ static void mmc_poweroff_notify(struct mmc_host
>>> *host)
>>>        int err = 0;
>>>
>>>        card = host->card;
>>> -
>>> +       mmc_claim_host(host);
>>> +
>>>        /*
>>>         * Send power notify command only if card
>>>         * is mmc and notify state is powered ON
>>> @@ -1269,6 +1270,7 @@ static void mmc_poweroff_notify(struct mmc_host
>>> *host)
>>>                /* Set the card state to no notification after the poweroff
>>> */
>>>                card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>>>        }
>>> +       mmc_release_host(host);
>>>  }
>>>
>>>  /*
>>> @@ -1327,12 +1329,28 @@ static void mmc_power_up(struct mmc_host *host)
>>>
>>>  void mmc_power_off(struct mmc_host *host)
>>>  {
>>> +       int err = 0;
>>>        mmc_host_clk_hold(host);
>>>
>>>        host->ios.clock = 0;
>>>        host->ios.vdd = 0;
>>>
>>> -       mmc_poweroff_notify(host);
>>> +       /*
>>> +        * For eMMC 4.5 device send AWAKE command before
>>> +        * POWER_OFF_NOTIFY command, because in sleep state
>>> +        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
>>> +        */
>>> +       if (host->card&&  mmc_card_is_sleep(host->card)&&
>>> +           host->bus_ops->resume) {
>>> +               err = host->bus_ops->resume(host);
>>
>>
>> This is just plain wrong. First we may have suspended the host from
>> mmc_suspend_host then we enter this funtion (mmc_power_off) to cut the power
>> to the card. Why do we even want to resume if we just did suspend?
> for 4.5 case, cards wont respond to any command other than awake and
> reset. so we resume before executing a switch
> for poweroff notify. for non 4.5 card, it will resume and wont
> continue in resume state because of the poweroff executed in the end.
>>
>> Moreover, this will actually mean that for mmc devices which are supporting
>> SLEEP but not the new eMMC 4.5 feature poweroff_notify will leave this
>> function in a resumed state (in other words, not in SLEEP state) which is
>> not OK.
> non 4.5 devices will not remain in resume state. Because mmc_set_ios
> will power down the device.
>>
>>
>>> +
>>> +               if (!err)
>>> +                       mmc_poweroff_notify(host);
>>> +               else
>>> +                       pr_warning("%s: error %d during resume "
>>> +                                  "(continue with poweroff sequence)\n",
>>> +                                  mmc_hostname(host), err);
>>> +       }
>>>
>>>        /*
>>>         * Reset ocr mask to be the highest possible voltage supported for
>>> @@ -2386,12 +2404,6 @@ int mmc_suspend_host(struct mmc_host *host)
>>>                 */
>>>                if (mmc_try_claim_host(host)) {
>>>                        if (host->bus_ops->suspend) {
>>> -                               /*
>>> -                                * For eMMC 4.5 device send notify command
>>> -                                * before sleep, because in sleep state
>>> eMMC 4.5
>>> -                                * devices respond to only RESET and AWAKE
>>> cmd
>>> -                                */
>>> -                               mmc_poweroff

Re: [PATCH v5 2/2] mmc: core: Support packed command for eMMC4.5 device

2012-03-04 Thread Saugata Das
Hi Merez

On 2 March 2012 19:56,   wrote:
> Hi,
>
> Our tests showed that the write packing improved the performance of the
> write sequential operations:
>
> Long write operation:
> --
> no-packing: 15.8 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 23.3 MB/s
>
> Several parallel write operations (sum of all the write throughputs):
> ---
> no-packing: 17.1 MB/s
> packed commands patch(both READ and WRITE packing are enabled): 25 MB/s
>
> Parallel long read and long write operations (write throughput):
> -
> no-packing: 12.2 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 16.3 MB/s
>
> Parallel short read and long write operations (write throughput):
> -
> no-packing: 15.4 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 16.4 MB/s
>
> Several Parallel short read and short write operations (sum of all the
> write throughputs):
> --
> no-packing: 12.5 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 15.5 MB/s
>

How did you perform the above tests ?

>
> Random read and random write:
> --
> I checked the random read and random write IOPs by using the IOZONE
> application. There was a slight degradation in the read results due to the
> packing and no improvements in the write results.
>
> The results are:
>
> IOZONE file size of 100M:
> no-packing: random read: 4675, random write: 729
> packed commands patch (both READ and WRITE packing are enabled): random
> read: 4557 random write: 723
>
> IOZONE file size of 256M:
> no-packing: random read: 4632, random write: 744
> packed commands patch (both READ and WRITE packing are enabled): random
> read: 4498, random write: 742
>
> Thanks,
> Maya Erez
> Consultant for Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
>> Hi. merez.
>>
>> Would you share random read speed with us ?
>>
>> And Write speed also..
>>
>> Thanks.
>>
>> 2012/3/1  :
 This patch supports packed command of eMMC4.5 device.
 Several reads(or writes) can be grouped in packed command
 and all data of the individual commands can be sent in a
 single transfer on the bus.

 Signed-off-by: Seungwon Jeon 
 ---
  drivers/mmc/card/block.c   |  496
 +--
  drivers/mmc/card/queue.c   |   48 -
  drivers/mmc/card/queue.h   |   13 ++
  drivers/mmc/core/mmc_ops.c |    1 +
  include/linux/mmc/core.h   |    4 +
  5 files changed, 535 insertions(+), 27 deletions(-)

>>> Hi,
>>>
>>> We ran performance tests on the packed commands patch. We found out that
>>> enabling the read packing didn't improve the performance in any of the
>>> scenarios we ran (see the detailed results below).
>>> Therefore, we suggest to move the read packing code to a different patch
>>> and approve only the write packing code for now. The read packing adds
>>> complexity to the code and we don't see a point in adding it while the
>>> intention is to disable it.
>>>
>>> Test results:
>>>
>>> Long read operation:
>>> --
>>> no-packing: 39.5 MB/s
>>> packed commands patch (both READ and WRITE packing are enabled): 39.5
>>> MB/s
>>> packed commands patch + enabling only READ packing: 39.5 MB/s
>>>
>>> Several parallel read operations (sum of all the read throughputs):
>>> ---
>>> no-packing: 42.6 MB/s
>>> packed commands patch(both READ and WRITE packing are enabled): 38 MB/s
>>> packed commands patch + enabling only READ packing: 38.2 MB/s
>>>
>>> Parallel long read and long write operations (read throughput):
>>> -
>>> no-packing: 23.8 MB/s
>>> packed commands patch (both READ and WRITE packing are enabled): 12.6
>>> MB/s
>>> packed commands patch + enabling only READ packing: 12.5 MB/s
>>>
>>> Parallel short read and long write operations (read throughput):
>>> -
>>> no-packing: 22.9 MB/s
>>> packed commands patch (both READ and WRITE packing are enabled): 8.4
>>> MB/s
>>> packed commands patch + enabling only READ packing: 8.6 MB/s
>>>
>>> Several Parallel short read and short write operations (sum of all the
>>> read throughputs):
>>> --
>>> no-packing: 41.6 MB/s
>>> packed commands patch (both READ and WRITE packing are enabled): 35 MB/s
>>> packed commands patch + enabling only READ packing: 36 MB/s
>>>
>>> Thanks,
>>> Maya Erez
>>> Consultant for Qualcomm Innovation Center, Inc.
>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>>>
>>>
>>>
>>>
>>>
>>> --
>>> To un

Re: [PATCH v5 2/2] mmc: core: Support packed command for eMMC4.5 device

2012-03-01 Thread Saugata Das
On 29 February 2012 23:40,   wrote:
>> This patch supports packed command of eMMC4.5 device.
>> Several reads(or writes) can be grouped in packed command
>> and all data of the individual commands can be sent in a
>> single transfer on the bus.
>>
>> Signed-off-by: Seungwon Jeon 
>> ---
>>  drivers/mmc/card/block.c   |  496
>> +--
>>  drivers/mmc/card/queue.c   |   48 -
>>  drivers/mmc/card/queue.h   |   13 ++
>>  drivers/mmc/core/mmc_ops.c |    1 +
>>  include/linux/mmc/core.h   |    4 +
>>  5 files changed, 535 insertions(+), 27 deletions(-)
>>
> Hi,
>
> We ran performance tests on the packed commands patch. We found out that
> enabling the read packing didn't improve the performance in any of the
> scenarios we ran (see the detailed results below).
> Therefore, we suggest to move the read packing code to a different patch
> and approve only the write packing code for now. The read packing adds
> complexity to the code and we don't see a point in adding it while the
> intention is to disable it.

Have  you seen improvement in the write packing ?


>
> Test results:
>
> Long read operation:
> --
> no-packing: 39.5 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 39.5 MB/s
> packed commands patch + enabling only READ packing: 39.5 MB/s
>
> Several parallel read operations (sum of all the read throughputs):
> ---
> no-packing: 42.6 MB/s
> packed commands patch(both READ and WRITE packing are enabled): 38 MB/s
> packed commands patch + enabling only READ packing: 38.2 MB/s
>
> Parallel long read and long write operations (read throughput):
> -
> no-packing: 23.8 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 12.6 MB/s
> packed commands patch + enabling only READ packing: 12.5 MB/s
>
> Parallel short read and long write operations (read throughput):
> -
> no-packing: 22.9 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 8.4 MB/s
> packed commands patch + enabling only READ packing: 8.6 MB/s
>
> Several Parallel short read and short write operations (sum of all the
> read throughputs):
> --
> no-packing: 41.6 MB/s
> packed commands patch (both READ and WRITE packing are enabled): 35 MB/s
> packed commands patch + enabling only READ packing: 36 MB/s
>
> Thanks,
> Maya Erez
> Consultant for Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7] mmc: support BKOPS feature for eMMC

2012-02-24 Thread Saugata Das
Hi Jaehoon

Since you are planning to rework this patch, can you consider to
implement the periodic BKOPS level check and triggering BKOPS at level
1 when the queue is idle ?


On 24 February 2012 14:08, Jaehoon Chung  wrote:
> On 02/23/2012 06:05 PM, Adrian Hunter wrote:
>
>> On 23/02/12 04:21, Jaehoon Chung wrote:
>>> On 02/22/2012 11:11 PM, Adrian Hunter wrote:
>>>
 On 20/01/12 08:48, Jaehoon Chung wrote:
> Enable eMMC background operations (BKOPS) feature.
>
> If URGENT_BKOPS is set after a response, note that BKOPS
> are required. After all I/O requests are finished, run
> BKOPS if required. Should read/write operations be requested
> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
> and then service the request.

 You are leaving bkops running and releasing the host.  Won't
 that cause problems for other entry points to mmc services
 e.g. system suspend (cache control, sleep etc), ioctl, sysfs,
 etc
>>>
>>> I see. i will complement for your review.
>>
>> Please cc me.
>
> Sure..
>
>>
>>> Didn't you have the other comment?
>>
>> Well, yes.  I also suggest:
>>       - don't use host->lock spin lock at all
>>       - claim the host in the caller not in
>>       mmc_start_bkops()
>>
>> But the main issues are design issues not implementation.
>> i.e.
>>       - always run bkops at level 3 before doing any
>>       other requests - that requirement should probably
>>       be implemented in core rather than the block driver
>
> In core..it's reasonable..i will try that.
>
>>       - do not release the host while bkops are running
>
> Right..don't release the host. i will consider.
>
>>
>> And a new one:
>>       - how do you know that trim/discard/sanitize will not
>>       result in a need for bkops?
>
> Well, i didn't consider that case.
> but i think that need to control them.
>
> Thanks for comments.
>
> Best Regards,
> Jaehoon Chung
>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7] mmc: support BKOPS feature for eMMC

2012-02-14 Thread Saugata Das
On 20 January 2012 12:18, Jaehoon Chung  wrote:
> Enable eMMC background operations (BKOPS) feature.
>
> If URGENT_BKOPS is set after a response, note that BKOPS
> are required. After all I/O requests are finished, run
> BKOPS if required. Should read/write operations be requested
> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
> and then service the request.
> If BKOPS-STATUS is upper than LEVEL2, need to check until clear
> the BKOPS-STATUS vaule.
>
> If you want to enable this feature, set MMC_CAP2_BKOPS.
> And if you want to set the BKOPS_EN bit in ext_csd register,
> use the MMC_CAP2_INIT_BKOPS.
>
> Future considerations
>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>  * Interrupt ongoing BKOPS before powering off the card.
>  * How get BKOPS_STATUS value.(periodically send ext_csd command?)

Do you have some statistics on the total size of the write operations
which triggers the "urgent BKOPS" situation on a given eMMC and how
much time does it take to complete the BKOPS ?

>
> Signed-off-by: Jaehoon Chung 
> Signed-off-by: Kyungmin Park 
> ---
> Changelog V7:
>        - Use HPI command when issued URGENT_BKOPS
>        - Recheck until clearing the bkops-status bit.
> Changelog V6:
>        - Add the flag of check-bkops-status.
>          (For fixing async_req problem)
>        - Add the capability for MMC_CAP2_INIT_BKOPS.
>          (When unset the bkops_en bit in ext_csd register)
>        - modify the wrong condition.
> Changelog V5:
>        - Rebase based on the latest mmc-next.
>        - modify codes based-on Chris's comment
> Changelog V4:
>        - Add mmc_read_bkops_status
>        - When URGENT_BKOPS(level2-3), didn't use HPI command.
>        - In mmc_switch(), use R1B/R1 according to level.
> Changelog V3:
>        - move the bkops setting's location in mmc_blk_issue_rw_rq
>        - modify condition checking
>        - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>        - remove the unused code
>        - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>        - Add the Future consideration suggested by Per
> Changelog V2:
>        - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>        - Add function to check Exception_status(for eMMC4.5)
>
>  drivers/mmc/card/block.c   |    7 +++
>  drivers/mmc/card/queue.c   |    5 ++
>  drivers/mmc/core/core.c    |  120 
> 
>  drivers/mmc/core/mmc.c     |   18 +++
>  drivers/mmc/core/mmc_ops.c |   11 -
>  include/linux/mmc/card.h   |   20 +++
>  include/linux/mmc/core.h   |    4 ++
>  include/linux/mmc/host.h   |    2 +
>  include/linux/mmc/mmc.h    |   19 +++
>  9 files changed, 205 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index 176b78e..7e8a154 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -1284,6 +1284,13 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
> struct request *rqc)
>                type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
>                mmc_queue_bounce_post(mq_rq);
>
> +               /*
> +                * Check BKOPS urgency from each R1 response
> +                */
> +               if (mmc_card_mmc(card) &&
> +                       (brq->cmd.resp[0] & R1_EXCEPTION_EVENT))
> +                       mmc_card_set_check_bkops(card);
> +
>                switch (status) {
>                case MMC_BLK_SUCCESS:
>                case MMC_BLK_PARTIAL:
> diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
> index 2517547..839735c 100644
> --- a/drivers/mmc/card/queue.c
> +++ b/drivers/mmc/card/queue.c
> @@ -66,6 +66,9 @@ static int mmc_queue_thread(void *d)
>                spin_unlock_irq(q->queue_lock);
>
>                if (req || mq->mqrq_prev->req) {
> +                       if (mmc_card_doing_bkops(mq->card))
> +                               mmc_interrupt_bkops(mq->card);
> +

If the "req" is a Write request, then probably it is not a good idea
to interrupt the background operation since due to the "urgent"
garbage level the Write will be anyway slower.


>                        set_current_state(TASK_RUNNING);
>                        mq->issue_fn(mq, req);
>                } else {
> @@ -73,6 +76,8 @@ static int mmc_queue_thread(void *d)
>                                set_current_state(TASK_RUNNING);
>                                break;
>                        }
> +
> +                       mmc_start_bkops(mq->card);
>                        up(&mq->thread_sem);
>                        schedule();
>                        down(&mq->thread_sem);
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index bec0bf2..8530b38 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -238,6 +238,62 @@ mmc_start_request(struct mmc_host *host, struct 
> mmc_request *mrq)
>        host->ops->request(host, mrq);
>  }
>
> +/**
> + *     mmc_s

Re: [RFC] MMC-4.5 Context ID

2012-02-13 Thread Saugata Das
On 12 February 2012 02:27, Chris Ball  wrote:
> Hi,
>
> On Mon, Feb 06 2012, Saugata Das wrote:
>> Thanks for the info. Perhaps the initial MMC-4.5 device samples do not
>> implement this command well. Yes, this feature is good to have in the
>> kernel. I shall wait for some more comments on the proposed
>> implementation before submitting the patch.
>
> I'm not very excited about merging features that offer no concrete
> benefit, because it just grows the kernel (and list of places where bugs
> can occur) for no benefit.  So, it would be great if we could find a
> device that actually implements these contexts in a way that provides
> a performance benefit, to prove that adding the code is worthwhile.
>

Completely agree with you. The purpose of proposing this
implementation under [RFC] was to trigger some discussion on how this
feature should be implemented.

> Thanks,
>
> - Chris.
> --
> Chris Ball      <http://printf.net/>
> One Laptop Per Child
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: core: Substitute mmc_flush_cash for mmc_cache_ctrl in suspend

2012-02-13 Thread Saugata Das
On 10 February 2012 09:26, Seungwon Jeon  wrote:
> After the cache is disabled in suspend, enabling cache can be done by
> mmc_init_card in resume. Currently this call path has been changed. In
> case of sleep mode mmc_init_card isn't called. So mmc_cache_ctrl need to
> be replaced with mmc_flush_cache in suspend.
>
> Signed-off-by: Seungwon Jeon 
> ---
>  drivers/mmc/core/core.c |    9 +++--
>  1 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 8a19143..70e25d8 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -2329,9 +2329,14 @@ EXPORT_SYMBOL(mmc_card_can_sleep);
>  */
>  int mmc_flush_cache(struct mmc_card *card)
>  {
> -       struct mmc_host *host = card->host;
> +       struct mmc_host *host;
>        int err = 0;
>
> +       if (!card)
> +               return err;
> +
> +       host = card->host;
> +
>        if (!(host->caps2 & MMC_CAP2_CACHE_CTRL))
>                return err;
>
> @@ -2401,7 +2406,7 @@ int mmc_suspend_host(struct mmc_host *host)
>        cancel_delayed_work(&host->detect);
>        mmc_flush_scheduled_work();
>        if (mmc_try_claim_host(host)) {
> -               err = mmc_cache_ctrl(host, 0);
> +               err = mmc_flush_cache(host->card);
>                mmc_do_release_host(host);
>        } else {
>                err = -EBUSY;
> --
> 1.7.0.4

Thanks for the changes.
Reviewed-by: Saugata Das 

>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] MMC-4.5 Context ID

2012-02-05 Thread Saugata Das
On 6 February 2012 10:56, Jaehoon Chung  wrote:
> On 02/06/2012 02:13 PM, Saugata Das wrote:
>
>> On 5 February 2012 08:15, Chris Ball  wrote:
>>> Hi,
>>>
>>> On Wed, Feb 01 2012, Saugata Das wrote:
>>>> From: Saugata Das 
>>>>
>>>> This patch groups the read or write transfers to eMMC in different contexts
>>>> based on the block number. Transfers to consecutive blocks are grouped to a
>>>> common context. So several small transfers combine to give performance like
>>>> a large multi block transfer.
>>>>
>>>> The patch creates a context of 1MB multiple in non-large unit mode. 
>>>> Reliable
>>>> mode is enabled in the context based on whether reliable write is enabled.
>>>
>>> Do you see any performance changes with this patchset?  If so, can you
>>> give details?
>>
>> I do not see any performance impact (positive or negative) on the
>> sample eMMC-4.5 device which I have. This could be due to the slow
>> bridge which I use (1-bit mode at 25MHz) to connect the eMMC-4.5
>> device on micro-SD slot of 8500 platform.
>
> I think that should be increased the performance by how we select the context.
> I also didn't see any performance benefit..8-bit mode at 50Mhz.
> But i have interest for this feature
>

Thanks for the info. Perhaps the initial MMC-4.5 device samples do not
implement this command well. Yes, this feature is good to have in the
kernel. I shall wait for some more comments on the proposed
implementation before submitting the patch.


> Best Regards,
> Jaehoon Chung
>
>>
>>>
>>> Thanks,
>>>
>>> - Chris.
>>> --
>>> Chris Ball      <http://printf.net/>
>>> One Laptop Per Child
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majord...@vger.kernel.org
>>> 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 majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] MMC-4.5 Context ID

2012-02-05 Thread Saugata Das
On 5 February 2012 08:15, Chris Ball  wrote:
> Hi,
>
> On Wed, Feb 01 2012, Saugata Das wrote:
>> From: Saugata Das 
>>
>> This patch groups the read or write transfers to eMMC in different contexts
>> based on the block number. Transfers to consecutive blocks are grouped to a
>> common context. So several small transfers combine to give performance like
>> a large multi block transfer.
>>
>> The patch creates a context of 1MB multiple in non-large unit mode. Reliable
>> mode is enabled in the context based on whether reliable write is enabled.
>
> Do you see any performance changes with this patchset?  If so, can you
> give details?

I do not see any performance impact (positive or negative) on the
sample eMMC-4.5 device which I have. This could be due to the slow
bridge which I use (1-bit mode at 25MHz) to connect the eMMC-4.5
device on micro-SD slot of 8500 platform.

>
> Thanks,
>
> - Chris.
> --
> Chris Ball      <http://printf.net/>
> One Laptop Per Child
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] MMC-4.5 Context ID

2012-02-02 Thread Saugata Das
On 3 February 2012 08:15, Jaehoon Chung  wrote:
> On 02/03/2012 01:08 AM, S, Venkatraman wrote:
>
>> On Wed, Feb 1, 2012 at 8:57 PM, Saugata Das  
>> wrote:
>>> From: Saugata Das 
>>>
>>> This patch groups the read or write transfers to eMMC in different contexts
>>> based on the block number. Transfers to consecutive blocks are grouped to a
>>> common context. So several small transfers combine to give performance like
>>> a large multi block transfer.
>>>
>>> The patch creates a context of 1MB multiple in non-large unit mode. Reliable
>>> mode is enabled in the context based on whether reliable write is enabled.
>>>
>>> Signed-off-by: Saugata Das 
>>> ---
>> The patch subject could be better off as "mmc: eMMC4.5 context ID support"
>>
>>>  drivers/mmc/card/block.c |  263 
>>> ++
>>>  drivers/mmc/core/mmc.c   |    6 +
>>>  include/linux/mmc/card.h |   13 +++
>>>  include/linux/mmc/core.h |    9 ++
>>>  include/linux/mmc/host.h |    1 +
>>>  include/linux/mmc/mmc.h  |    3 +
>>>  6 files changed, 275 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>> index 176b78e..161174a 100644
>>> --- a/drivers/mmc/card/block.c
>>> +++ b/drivers/mmc/card/block.c
>>> @@ -127,6 +127,8 @@ enum mmc_blk_status {
>>>  module_param(perdev_minors, int, 0444);
>>>  MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
>>>
>>> +static int mmc_blk_issue_rw_rq(struct mmc_queue *, struct request *);
>>> +
>>>  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
>>>  {
>>>        struct mmc_blk_data *md;
>>> @@ -1071,6 +1073,192 @@ static int mmc_blk_err_check(struct mmc_card *card,
>>>        return MMC_BLK_SUCCESS;
>>>  }
>>>
>>> +/*
>>> + * Update the context information in the ext. CSD
>>
>> Mixed case
>>
>>> + */
>>> +static int mmc_context_modify(struct mmc_queue *mq,
>>> +                               struct mmc_card *card,
>>> +                               unsigned int context_id,
>>> +                               unsigned char context_conf)
>>> +{
>>> +       /*
>>> +        * Wait for any ongoing transfer
>>> +        */
>>> +       if (card->host->areq)
>>> +               mmc_blk_issue_rw_rq(mq, NULL);
>>> +
>>> +       /*
>>> +        * CONTEXT_CONF array starts from context id 1
>>> +        */
>>> +       return mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> +                       EXT_CSD_CONTEXT_CONF + context_id - 1,
>>> +                       context_conf,
>>> +                       card->ext_csd.generic_cmd6_time);
>>> +}
>>> +
>>> +/*
>>> + * Update timestamp, size and close context if needed
>>> + */
>>> +static int mmc_check_close_context(struct mmc_queue *mq,
>>> +                               struct mmc_card *card,
>>> +                               unsigned int context_id,
>>> +                               unsigned int status)
>>> +{
>>> +       /*
>>> +        * Check only for valid contexts
>>> +        */
>>> +       if ((context_id > 0) &&
>>> +               (context_id <= card->ext_csd.max_context_id) &&
>>> +               (card->mmc_context[context_id].valid)) {
>>> +
>>> +               /*
>>> +                * Incase of an error or we are multiple of erase block then
>>> +                * close the context
>>> +                */
>>> +               if ((status) ||
>>> +                       ((card->mmc_context[context_id].size %
>>> +                               card->ext_csd.lu_size) == 0)) {
>>> +                       if (mmc_context_modify(mq, card, context_id,
>>> +                                       MMC_CONTEXT_CLOSE))
>>> +                               return -1;
>> Should propagate the error code instead of returning -1
>>
>>> +                       card->mmc_context[context_id].valid = 0;
>>> +               }
>>> +               return 0;
>>> +       }
>>> +       return 0;
>>> +}
>>> +
>>> +/*
>>> + * Update timestamp, size and close context if needed
>>> + */
>

Re: [RFC] MMC-4.5 Context ID

2012-02-02 Thread Saugata Das
On 2 February 2012 21:38, S, Venkatraman  wrote:
> On Wed, Feb 1, 2012 at 8:57 PM, Saugata Das  
> wrote:
>> From: Saugata Das 
>>
>> This patch groups the read or write transfers to eMMC in different contexts
>> based on the block number. Transfers to consecutive blocks are grouped to a
>> common context. So several small transfers combine to give performance like
>> a large multi block transfer.
>>
>> The patch creates a context of 1MB multiple in non-large unit mode. Reliable
>> mode is enabled in the context based on whether reliable write is enabled.
>>
>> Signed-off-by: Saugata Das 
>> ---
> The patch subject could be better off as "mmc: eMMC4.5 context ID support"

OK

>
>>  drivers/mmc/card/block.c |  263 
>> ++
>>  drivers/mmc/core/mmc.c   |    6 +
>>  include/linux/mmc/card.h |   13 +++
>>  include/linux/mmc/core.h |    9 ++
>>  include/linux/mmc/host.h |    1 +
>>  include/linux/mmc/mmc.h  |    3 +
>>  6 files changed, 275 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index 176b78e..161174a 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -127,6 +127,8 @@ enum mmc_blk_status {
>>  module_param(perdev_minors, int, 0444);
>>  MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
>>
>> +static int mmc_blk_issue_rw_rq(struct mmc_queue *, struct request *);
>> +
>>  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
>>  {
>>        struct mmc_blk_data *md;
>> @@ -1071,6 +1073,192 @@ static int mmc_blk_err_check(struct mmc_card *card,
>>        return MMC_BLK_SUCCESS;
>>  }
>>
>> +/*
>> + * Update the context information in the ext. CSD
>
> Mixed case

OK

>
>> + */
>> +static int mmc_context_modify(struct mmc_queue *mq,
>> +                               struct mmc_card *card,
>> +                               unsigned int context_id,
>> +                               unsigned char context_conf)
>> +{
>> +       /*
>> +        * Wait for any ongoing transfer
>> +        */
>> +       if (card->host->areq)
>> +               mmc_blk_issue_rw_rq(mq, NULL);
>> +
>> +       /*
>> +        * CONTEXT_CONF array starts from context id 1
>> +        */
>> +       return mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                       EXT_CSD_CONTEXT_CONF + context_id - 1,
>> +                       context_conf,
>> +                       card->ext_csd.generic_cmd6_time);
>> +}
>> +
>> +/*
>> + * Update timestamp, size and close context if needed
>> + */
>> +static int mmc_check_close_context(struct mmc_queue *mq,
>> +                               struct mmc_card *card,
>> +                               unsigned int context_id,
>> +                               unsigned int status)
>> +{
>> +       /*
>> +        * Check only for valid contexts
>> +        */
>> +       if ((context_id > 0) &&
>> +               (context_id <= card->ext_csd.max_context_id) &&
>> +               (card->mmc_context[context_id].valid)) {
>> +
>> +               /*
>> +                * Incase of an error or we are multiple of erase block then
>> +                * close the context
>> +                */
>> +               if ((status) ||
>> +                       ((card->mmc_context[context_id].size %
>> +                               card->ext_csd.lu_size) == 0)) {
>> +                       if (mmc_context_modify(mq, card, context_id,
>> +                                       MMC_CONTEXT_CLOSE))
>> +                               return -1;
> Should propagate the error code instead of returning -1
>

OK

>> +                       card->mmc_context[context_id].valid = 0;
>> +               }
>> +               return 0;
>> +       }
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Update timestamp, size and close context if needed
>> + */
>> +static int mmc_force_close_all_write_context(struct mmc_queue *mq,
>> +                               struct mmc_card *card)
>> +{
>> +       int i, ret = 0;
>> +       for (i = 1; i <= card->ext_csd.max_context_id; i++) {
>> +               if (card->mmc_context[i].direction != MMC_CONTEXT_READ) {
>> +                       ret = mmc_check_close_context(mq, card, i,
>> +                             

[PATCH V2] mmci.c: CMD23 support

2012-02-01 Thread Saugata Das
From: Saugata Das 

Support added for transmission of CMD23 during multi block read or
write. In order to activate this feature, MMC_CAP_CMD23 flag needs
to be enabled in the capabilities field. Note that CMD23 support is
mandatory to support features like reliable write, data tag, context
ID, packed command.

Signed-off-by: Saugata Das 
Acked-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8eabf99..21f75da 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -726,7 +726,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
/* The error clause is handled above, success! */
data->bytes_xfered = data->blksz * data->blocks;
 
-   if (!data->stop) {
+   if (!data->stop || host->mrq->sbc) {
mmci_request_end(host, data->mrq);
} else {
mmci_start_command(host, data->stop, 0);
@@ -739,6 +739,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
 unsigned int status)
 {
void __iomem *base = host->base;
+   bool sbc = !!(host->mrq->sbc && (host->mrq->sbc == host->cmd));
 
host->cmd = NULL;
 
@@ -753,10 +754,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
cmd->resp[3] = readl(base + MMCIRESPONSE3);
}
 
-   if (!cmd->data || cmd->error) {
+   if ((!sbc && !cmd->data) || cmd->error) {
if (host->data)
mmci_stop_data(host);
mmci_request_end(host, cmd->mrq);
+   } else if (sbc) {
+   mmci_start_command(host, host->mrq->cmd, 0);
} else if (!(cmd->data->flags & MMC_DATA_READ)) {
mmci_start_data(host, cmd->data);
}
@@ -998,7 +1001,10 @@ static void mmci_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
if (mrq->data && mrq->data->flags & MMC_DATA_READ)
mmci_start_data(host, mrq->data);
 
-   mmci_start_command(host, mrq->cmd, 0);
+   if (mrq->sbc)
+   mmci_start_command(host, mrq->sbc, 0);
+   else
+   mmci_start_command(host, mrq->cmd, 0);
 
spin_unlock_irqrestore(&host->lock, flags);
 }
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: core: Fix PowerOff Notify suspend/resume

2012-02-01 Thread Saugata Das
        err = mmc_init_card(host, host->ocr, host->card);
>        mmc_release_host(host);
>
>        return err;
> @@ -1364,7 +1370,8 @@ static int mmc_power_restore(struct mmc_host *host)
>  {
>        int ret;
>
> -       host->card->state &= ~MMC_STATE_HIGHSPEED;
> +       host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
> +       mmc_card_clr_sleep(host->card);
>        mmc_claim_host(host);
>        ret = mmc_init_card(host, host->ocr, host->card);
>        mmc_release_host(host);
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index f9a0663..1a1ca71 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -219,6 +219,7 @@ struct mmc_card {
>  #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
>  #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 
> mode */
> +#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep 
> state */
>        unsigned int            quirks;         /* card quirks */
>  #define MMC_QUIRK_LENIENT_FN0  (1<<0)          /* allow SDIO FN0 writes 
> outside of the VS CCCR range */
>  #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)   /* use func->cur_blksize */
> @@ -384,6 +385,7 @@ static inline void __maybe_unused remove_quirk(struct 
> mmc_card *card, int data)
>  #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
>  #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
> +#define mmc_card_is_sleep(c)   ((c)->state & MMC_STATE_SLEEP)
>
>  #define mmc_card_set_present(c)        ((c)->state |= MMC_STATE_PRESENT)
>  #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
> @@ -395,7 +397,9 @@ static inline void __maybe_unused remove_quirk(struct 
> mmc_card *card, int data)
>  #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
>  #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
>  #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
> +#define mmc_card_set_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>
> +#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
>  /*
>  * Quirk add/remove for MMC products.
>  */
> --
> 1.7.1
>

Thanks for the changes.
Reviewed-by: Saugata Das 
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] MMC-4.5 Context ID

2012-02-01 Thread Saugata Das
From: Saugata Das 

This patch groups the read or write transfers to eMMC in different contexts
based on the block number. Transfers to consecutive blocks are grouped to a
common context. So several small transfers combine to give performance like
a large multi block transfer.

The patch creates a context of 1MB multiple in non-large unit mode. Reliable
mode is enabled in the context based on whether reliable write is enabled.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |  263 ++
 drivers/mmc/core/mmc.c   |6 +
 include/linux/mmc/card.h |   13 +++
 include/linux/mmc/core.h |9 ++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |3 +
 6 files changed, 275 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 176b78e..161174a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -127,6 +127,8 @@ enum mmc_blk_status {
 module_param(perdev_minors, int, 0444);
 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
 
+static int mmc_blk_issue_rw_rq(struct mmc_queue *, struct request *);
+
 static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
 {
struct mmc_blk_data *md;
@@ -1071,6 +1073,192 @@ static int mmc_blk_err_check(struct mmc_card *card,
return MMC_BLK_SUCCESS;
 }
 
+/*
+ * Update the context information in the ext. CSD
+ */
+static int mmc_context_modify(struct mmc_queue *mq,
+   struct mmc_card *card,
+   unsigned int context_id,
+   unsigned char context_conf)
+{
+   /*
+* Wait for any ongoing transfer
+*/
+   if (card->host->areq)
+   mmc_blk_issue_rw_rq(mq, NULL);
+
+   /*
+* CONTEXT_CONF array starts from context id 1
+*/
+   return mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CONTEXT_CONF + context_id - 1,
+   context_conf,
+   card->ext_csd.generic_cmd6_time);
+}
+
+/*
+ * Update timestamp, size and close context if needed
+ */
+static int mmc_check_close_context(struct mmc_queue *mq,
+   struct mmc_card *card,
+   unsigned int context_id,
+   unsigned int status)
+{
+   /*
+* Check only for valid contexts
+*/
+   if ((context_id > 0) &&
+   (context_id <= card->ext_csd.max_context_id) &&
+   (card->mmc_context[context_id].valid)) {
+
+   /*
+* Incase of an error or we are multiple of erase block then
+* close the context
+*/
+   if ((status) ||
+   ((card->mmc_context[context_id].size %
+   card->ext_csd.lu_size) == 0)) {
+   if (mmc_context_modify(mq, card, context_id,
+   MMC_CONTEXT_CLOSE))
+   return -1;
+   card->mmc_context[context_id].valid = 0;
+   }
+   return 0;
+   }
+   return 0;
+}
+
+/*
+ * Update timestamp, size and close context if needed
+ */
+static int mmc_force_close_all_write_context(struct mmc_queue *mq,
+   struct mmc_card *card)
+{
+   int i, ret = 0;
+   for (i = 1; i <= card->ext_csd.max_context_id; i++) {
+   if (card->mmc_context[i].direction != MMC_CONTEXT_READ) {
+   ret = mmc_check_close_context(mq, card, i,
+   MMC_CONTEXT_FORCE_CLOSE);
+   if (ret)
+   return ret;
+   }
+   }
+   return ret;
+}
+
+/*
+ * Search for a context which is in the same direction and
+ * continuous in block numbers. If no matching context is
+ * found then take up an unused context. If all contexts are
+ * used then close the context which is least recently used,
+ * close it and the use it for the new transfer
+ */
+static int mmc_get_context_id(struct mmc_queue *mq,
+   struct mmc_card *card,
+   unsigned int offset,
+   unsigned int size,
+   unsigned int direction,
+   unsigned int rel_wr)
+{
+   int i, free_index = -1, lru_index = -1, ret_index;
+   unsigned int old_timestamp = -1;
+   unsigned int reliability_mode = rel_wr ? (0x01<<5) : 0;
+   struct mmc_context *context_ptr = &card->mmc_context[1];
+
+   /*
+* For older than 4.5 eMMC, there is no context ID
+*/
+   if (card->ext_csd.max_context_id == 0)
+   return 0;
+
+   if (card->host->caps2 & MMC_C

[PATCH] mmci.c: CMD23 support

2012-01-31 Thread Saugata Das
From: Saugata Das 

Support added for transmission of CMD23 during multi block read or write. In 
order to activate this feature, MMC_CAP_CMD23 flag needs to be enabled in the 
capabilities field. Note that CMD23 support is mandatory to support features 
like reliable write, data tag, context ID, packed command

Signed-off-by: Saugata Das 
---
 drivers/mmc/host/mmci.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8eabf99..21f75da 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -726,7 +726,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
/* The error clause is handled above, success! */
data->bytes_xfered = data->blksz * data->blocks;
 
-   if (!data->stop) {
+   if (!data->stop || host->mrq->sbc) {
mmci_request_end(host, data->mrq);
} else {
mmci_start_command(host, data->stop, 0);
@@ -739,6 +739,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
 unsigned int status)
 {
void __iomem *base = host->base;
+   bool sbc = !!(host->mrq->sbc && (host->mrq->sbc == host->cmd));
 
host->cmd = NULL;
 
@@ -753,10 +754,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
cmd->resp[3] = readl(base + MMCIRESPONSE3);
}
 
-   if (!cmd->data || cmd->error) {
+   if ((!sbc && !cmd->data) || cmd->error) {
if (host->data)
mmci_stop_data(host);
mmci_request_end(host, cmd->mrq);
+   } else if (sbc) {
+   mmci_start_command(host, host->mrq->cmd, 0);
} else if (!(cmd->data->flags & MMC_DATA_READ)) {
mmci_start_data(host, cmd->data);
}
@@ -998,7 +1001,10 @@ static void mmci_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
if (mrq->data && mrq->data->flags & MMC_DATA_READ)
mmci_start_data(host, mrq->data);
 
-   mmci_start_command(host, mrq->cmd, 0);
+   if (mrq->sbc)
+   mmci_start_command(host, mrq->sbc, 0);
+   else
+   mmci_start_command(host, mrq->cmd, 0);
 
spin_unlock_irqrestore(&host->lock, flags);
 }
-- 
1.7.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 2/2] mmc: core: Support packed command for eMMC4.5 device

2012-01-27 Thread Saugata Das
On 27 January 2012 12:25, Seungwon Jeon  wrote:
> Saugata Das  wrote:
>> On 25 January 2012 10:47, Seungwon Jeon  wrote:
>> > Hi, Saugata Das.
>> >
>> > Saugata Das  wrote:
>> >> On 20 January 2012 09:36, Seungwon Jeon  wrote:
>> >> > This patch supports packed command of eMMC4.5 device.
>> >> > Several reads(or writes) can be grouped in packed command
>> >> > and all data of the individual commands can be sent in a
>> >> > single transfer on the bus.
>> >> >
>> >> > Signed-off-by: Seungwon Jeon 
>> >> > ---
>> >> >  drivers/mmc/card/block.c   |  469 
>> >> > +---
>> >> >  drivers/mmc/card/queue.c   |   48 +-
>> >> >  drivers/mmc/card/queue.h   |   13 ++
>> >> >  drivers/mmc/core/host.c    |    2 +
>> >> >  drivers/mmc/core/mmc_ops.c |    1 +
>> >> >  include/linux/mmc/core.h   |    3 +
>> >> >  include/linux/mmc/host.h   |    3 +
>> >> >  7 files changed, 512 insertions(+), 27 deletions(-)
>> >> >
>> >> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> >> > index 176b78e..77d457e 100644
>> >> > --- a/drivers/mmc/card/block.c
>> >> > +++ b/drivers/mmc/card/block.c
>> >> > @@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
>> >> >  #define INAND_CMD38_ARG_SECTRIM1 0x81
>> >> >  #define INAND_CMD38_ARG_SECTRIM2 0x88
>> >> >
>> >> > +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
>> >> > +                       (req->cmd_flags & REQ_META)) && \
>> >> > +                       (rq_data_dir(req) == WRITE))
>> >> > +#define PACKED_CMD_VER         0x01
>> >> > +#define PACKED_CMD_RD          0x01
>> >> > +#define PACKED_CMD_WR          0x02
>> >> > +
>> >> >  static DEFINE_MUTEX(block_mutex);
>> >> >
>> >> >  /*
>> >> > @@ -99,6 +106,7 @@ struct mmc_blk_data {
>> >> >  #define MMC_BLK_WRITE          BIT(1)
>> >> >  #define MMC_BLK_DISCARD                BIT(2)
>> >> >  #define MMC_BLK_SECDISCARD     BIT(3)
>> >> > +#define MMC_BLK_WR_HDR         BIT(4)
>> >> >
>> >> >        /*
>> >> >         * Only set in main mmc_blk_data associated
>> >> > @@ -1028,7 +1036,8 @@ static int mmc_blk_err_check(struct mmc_card 
>> >> > *card,
>> >> >         * kind.  If it was a write, we may have transitioned to
>> >> >         * program mode, which we have to wait for it to complete.
>> >> >         */
>> >> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
>> >> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) 
>> >> > ||
>> >> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
>> >> >                u32 status;
>> >> >                do {
>> >> >                        int err = get_card_status(card, &status, 5);
>> >> > @@ -1053,7 +1062,8 @@ static int mmc_blk_err_check(struct mmc_card 
>> >> > *card,
>> >> >                       (unsigned)blk_rq_sectors(req),
>> >> >                       brq->cmd.resp[0], brq->stop.resp[0]);
>> >> >
>> >> > -               if (rq_data_dir(req) == READ) {
>> >> > +               if (rq_data_dir(req) == READ &&
>> >> > +                               mq_mrq->packed_cmd != 
>> >> > MMC_PACKED_WR_HDR) {
>> >> >                        if (ecc_err)
>> >> >                                return MMC_BLK_ECC_ERR;
>> >> >                        return MMC_BLK_DATA_ERR;
>> >> > @@ -1065,12 +1075,60 @@ static int mmc_blk_err_check(struct mmc_card 
>> >> > *card,
>> >> >        if (!brq->data.bytes_xfered)
>> >> >                return MMC_BLK_RETRY;
>> >> >
>> >> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
>> >> > +               if (unlikely(brq->data.blocks << 9 != 
>> >> > brq->data.bytes_xfered))
>> >> > +                       return MMC_BLK_PA

Re: [PATCH v3 2/2] mmc: core: Support packed command for eMMC4.5 device

2012-01-26 Thread Saugata Das
On 25 January 2012 10:47, Seungwon Jeon  wrote:
> Hi, Saugata Das.
>
> Saugata Das  wrote:
>> On 20 January 2012 09:36, Seungwon Jeon  wrote:
>> > This patch supports packed command of eMMC4.5 device.
>> > Several reads(or writes) can be grouped in packed command
>> > and all data of the individual commands can be sent in a
>> > single transfer on the bus.
>> >
>> > Signed-off-by: Seungwon Jeon 
>> > ---
>> >  drivers/mmc/card/block.c   |  469 
>> > +---
>> >  drivers/mmc/card/queue.c   |   48 +-
>> >  drivers/mmc/card/queue.h   |   13 ++
>> >  drivers/mmc/core/host.c    |    2 +
>> >  drivers/mmc/core/mmc_ops.c |    1 +
>> >  include/linux/mmc/core.h   |    3 +
>> >  include/linux/mmc/host.h   |    3 +
>> >  7 files changed, 512 insertions(+), 27 deletions(-)
>> >
>> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> > index 176b78e..77d457e 100644
>> > --- a/drivers/mmc/card/block.c
>> > +++ b/drivers/mmc/card/block.c
>> > @@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
>> >  #define INAND_CMD38_ARG_SECTRIM1 0x81
>> >  #define INAND_CMD38_ARG_SECTRIM2 0x88
>> >
>> > +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
>> > +                       (req->cmd_flags & REQ_META)) && \
>> > +                       (rq_data_dir(req) == WRITE))
>> > +#define PACKED_CMD_VER         0x01
>> > +#define PACKED_CMD_RD          0x01
>> > +#define PACKED_CMD_WR          0x02
>> > +
>> >  static DEFINE_MUTEX(block_mutex);
>> >
>> >  /*
>> > @@ -99,6 +106,7 @@ struct mmc_blk_data {
>> >  #define MMC_BLK_WRITE          BIT(1)
>> >  #define MMC_BLK_DISCARD                BIT(2)
>> >  #define MMC_BLK_SECDISCARD     BIT(3)
>> > +#define MMC_BLK_WR_HDR         BIT(4)
>> >
>> >        /*
>> >         * Only set in main mmc_blk_data associated
>> > @@ -1028,7 +1036,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
>> >         * kind.  If it was a write, we may have transitioned to
>> >         * program mode, which we have to wait for it to complete.
>> >         */
>> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
>> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
>> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
>> >                u32 status;
>> >                do {
>> >                        int err = get_card_status(card, &status, 5);
>> > @@ -1053,7 +1062,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
>> >                       (unsigned)blk_rq_sectors(req),
>> >                       brq->cmd.resp[0], brq->stop.resp[0]);
>> >
>> > -               if (rq_data_dir(req) == READ) {
>> > +               if (rq_data_dir(req) == READ &&
>> > +                               mq_mrq->packed_cmd != MMC_PACKED_WR_HDR) {
>> >                        if (ecc_err)
>> >                                return MMC_BLK_ECC_ERR;
>> >                        return MMC_BLK_DATA_ERR;
>> > @@ -1065,12 +1075,60 @@ static int mmc_blk_err_check(struct mmc_card *card,
>> >        if (!brq->data.bytes_xfered)
>> >                return MMC_BLK_RETRY;
>> >
>> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
>> > +               if (unlikely(brq->data.blocks << 9 != 
>> > brq->data.bytes_xfered))
>> > +                       return MMC_BLK_PARTIAL;
>> > +               else
>> > +                       return MMC_BLK_SUCCESS;
>> > +       }
>> > +
>> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
>> >                return MMC_BLK_PARTIAL;
>> >
>> >        return MMC_BLK_SUCCESS;
>> >  }
>> >
>> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
>> > +                            struct mmc_async_req *areq)
>> > +{
>> > +       struct mmc_queue_req *mq_rq = container_of(areq, struct 
>> > mmc_queue_req,
>> > +                       mmc_active);
>> > +       struct request *req = mq_rq->req;
>> > +       int err, check, status;
>> > +       u8 ext_csd[512];
>> > +
>> > +       check = mmc_blk_err_check(card, areq);
>>

Re: [PATCH v3 0/2] mmc: core: Support packed command feature of eMMC4.5

2012-01-23 Thread Saugata Das
On 20 January 2012 10:05, Kyungmin Park  wrote:
> Hi,
>
> FYI: we get performance gain using packed command at write. however in
> case of small size read, there are some performance drop since
> protocol overhead.
> In normal case, read command uses read operation only, but in case of
> packed read. It sends the command to eMMC and read it.
> Anyway it's good feature for eMMC v4.5.
>

I believe the improvement will vary depending on how many commands are
packed, which will depend on use case (e.g. CPU load, rate of
application read/write), file system state (e.g. fragmentation, amount
of free space) etc. It will be very interesting if you can publish the
details of what you have tested and your observation of different
parameters related to packed command.


> Acked-by: Kyungmin Park 
>
> On 1/20/12, Seungwon Jeon  wrote:
>> This patch-set adds support of packed command feature
>> for eMMC4.5 devices.
>>
>> Changes in v3:
>>       - Add a variable member in mmc_host for minimum number of packed 
>> entries.
>>         This value can be overrided by host.
>>       - Fix a handling of error sequence.
>>
>> Changes in v2:
>>       - Fix the packed read sequence and error handling.
>>       - Apply checking the exception status for all cases with
>>         the comments from Maya Erez and Sahitya Tummala.
>>       - Fix preparing the packed list with the comment from Maya Erez and
>> Venkatraman.
>>
>>
>> Seungwon Jeon (2):
>>       mmc: core: Add packed command feature of eMMC4.5
>>       mmc: core: Support packed command for eMMC4.5 device
>>
>>  drivers/mmc/card/block.c   |  469
>> +---
>>  drivers/mmc/card/queue.c   |   48 +-
>>  drivers/mmc/card/queue.h   |   13 ++
>>  drivers/mmc/core/host.c    |    2 +
>>  drivers/mmc/core/mmc.c     |   24 +++
>>  drivers/mmc/core/mmc_ops.c |    1 +
>>  include/linux/mmc/card.h   |    3 +
>>  include/linux/mmc/core.h   |    3 +
>>  include/linux/mmc/host.h   |    4 +
>>  include/linux/mmc/mmc.h    |   15 ++
>>  10 files changed, 555 insertions(+), 27 deletions(-)
>>
>> Best regards,
>> Seungwon Jeon.
>> --
>> 1.7.2.3
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 2/2] mmc: core: Support packed command for eMMC4.5 device

2012-01-23 Thread Saugata Das
On 20 January 2012 09:36, Seungwon Jeon  wrote:
> This patch supports packed command of eMMC4.5 device.
> Several reads(or writes) can be grouped in packed command
> and all data of the individual commands can be sent in a
> single transfer on the bus.
>
> Signed-off-by: Seungwon Jeon 
> ---
>  drivers/mmc/card/block.c   |  469 
> +---
>  drivers/mmc/card/queue.c   |   48 +-
>  drivers/mmc/card/queue.h   |   13 ++
>  drivers/mmc/core/host.c    |    2 +
>  drivers/mmc/core/mmc_ops.c |    1 +
>  include/linux/mmc/core.h   |    3 +
>  include/linux/mmc/host.h   |    3 +
>  7 files changed, 512 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index 176b78e..77d457e 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
>  #define INAND_CMD38_ARG_SECTRIM1 0x81
>  #define INAND_CMD38_ARG_SECTRIM2 0x88
>
> +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
> +                       (req->cmd_flags & REQ_META)) && \
> +                       (rq_data_dir(req) == WRITE))
> +#define PACKED_CMD_VER         0x01
> +#define PACKED_CMD_RD          0x01
> +#define PACKED_CMD_WR          0x02
> +
>  static DEFINE_MUTEX(block_mutex);
>
>  /*
> @@ -99,6 +106,7 @@ struct mmc_blk_data {
>  #define MMC_BLK_WRITE          BIT(1)
>  #define MMC_BLK_DISCARD                BIT(2)
>  #define MMC_BLK_SECDISCARD     BIT(3)
> +#define MMC_BLK_WR_HDR         BIT(4)
>
>        /*
>         * Only set in main mmc_blk_data associated
> @@ -1028,7 +1036,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
>         * kind.  If it was a write, we may have transitioned to
>         * program mode, which we have to wait for it to complete.
>         */
> -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
> +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
> +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
>                u32 status;
>                do {
>                        int err = get_card_status(card, &status, 5);
> @@ -1053,7 +1062,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
>                       (unsigned)blk_rq_sectors(req),
>                       brq->cmd.resp[0], brq->stop.resp[0]);
>
> -               if (rq_data_dir(req) == READ) {
> +               if (rq_data_dir(req) == READ &&
> +                               mq_mrq->packed_cmd != MMC_PACKED_WR_HDR) {
>                        if (ecc_err)
>                                return MMC_BLK_ECC_ERR;
>                        return MMC_BLK_DATA_ERR;
> @@ -1065,12 +1075,60 @@ static int mmc_blk_err_check(struct mmc_card *card,
>        if (!brq->data.bytes_xfered)
>                return MMC_BLK_RETRY;
>
> +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> +               if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
> +                       return MMC_BLK_PARTIAL;
> +               else
> +                       return MMC_BLK_SUCCESS;
> +       }
> +
>        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
>                return MMC_BLK_PARTIAL;
>
>        return MMC_BLK_SUCCESS;
>  }
>
> +static int mmc_blk_packed_err_check(struct mmc_card *card,
> +                            struct mmc_async_req *areq)
> +{
> +       struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req,
> +                       mmc_active);
> +       struct request *req = mq_rq->req;
> +       int err, check, status;
> +       u8 ext_csd[512];
> +
> +       check = mmc_blk_err_check(card, areq);
> +       err = get_card_status(card, &status, 0);
> +       if (err) {
> +               pr_err("%s: error %d sending status command\n",
> +                               req->rq_disk->disk_name, err);
> +               return MMC_BLK_ABORT;
> +       }
> +
> +       if (status & R1_EXP_EVENT) {
> +               err = mmc_send_ext_csd(card, ext_csd);
> +               if (err) {
> +                       pr_err("%s: error %d sending ext_csd\n",
> +                                       req->rq_disk->disk_name, err);
> +                       return MMC_BLK_ABORT;
> +               }
> +
> +               if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] &
> +                                       EXT_CSD_PACKED_FAILURE) &&
> +                               (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
> +                                EXT_CSD_PACKED_GENERIC_ERROR)) {
> +                       if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
> +                                       EXT_CSD_PACKED_INDEXED_ERROR) {
> +                               mq_rq->packed_fail_idx =
> +                                       ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] 
> - 1;
> +                               return MMC_BLK_PARTIAL;
> +                       }
> +               }
> +       }
> +
> +       return check;
> +}
> +
>  static void mmc_blk_rw_rq_

Re: [PATCH] MMC-4.5 Data Tag Support

2012-01-18 Thread Saugata Das
On 18 January 2012 18:45, Kyungmin Park  wrote:
> On Tue, Jan 17, 2012 at 10:40 PM, S, Venkatraman  wrote:
>> On Mon, Jan 16, 2012 at 6:39 PM, Kyungmin Park  wrote:
>>> On Mon, Jan 16, 2012 at 7:37 PM, S, Venkatraman  wrote:
>>>> On Fri, Jan 13, 2012 at 3:40 PM, Kyungmin Park  
>>>> wrote:
>>>>> On 1/13/12, Chris Ball  wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Thu, Jan 12 2012, S, Venkatraman wrote:
>>>>>>> On Wed, Dec 21, 2011 at 1:09 PM, Saugata Das 
>>>>>>> 
>>>>>>> wrote:
>>>>>>>> From: Saugata Das 
>>>>>>>>
>>>>>>>> MMC-4.5 data tag feature will be used to store the file system
>>>>>>>> meta-data in the
>>>>>>>> tagged region of eMMC. This will improve the write and subsequent
>>>>>>>> read transfer
>>>>>>>> time for the meta data.
>>>>>>>>
>>>>>>>> Signed-off-by: Saugata Das 
>>>>>>>
>>>>>>> I tested this on a device which supports a data tag unit size of 8K.
>>>>>>> Tested-by: Venkatraman S 
>>>>>>
>>>>>> Thanks for testing!  I've pushed it to mmc-next.
>>>>>>
>>>>>>> Chris,
>>>>>>>   Can this go into 3.3 ?
>>>>>>
>>>>>> I think 3.4 would be better after a full round of linux-next testing,
>>>>>> since this sounds like it could expose card-dependent quirks that could
>>>>>> destroy filesystems.  Better to be safe.
>>>>> I'm afraid it that it's really required since some features. data tag,
>>>>> context id, and packed command, are not mutual exclusive. so I hope to
>>>>> make it select. I mean it's not measured the real performance gain
>>>>> and/or other feature. so hope to enable/disable by platform data.
>>>>>
>>>>> How do you think?
>>>>>
>>>>> Thank you,
>>>>> Kyungmin Park
>>>>
>>>> I don't understand your comment on them not being mutually exclusive.
>>>> As it is, these are core features and they don't belong in platform data.
>>>> Can you explain a bit more ?
>>> To get the gain these features, data tag, context ID, it requires the
>>> firmware support.
>>> But currently there's no idea to support these feature at firmware. So
>>> we can't get the valuable performance gain.
>>
>> But that's neither a kernel issue, nor is a 'regression'. At worst,
>> the card should behave like a 4.41 standard card for an unoptimized firmware.
> Basically I agree that implement the codes by Spec. but it doesn't
> mean all features are required for eMMC.
> At some condition. frequent suspend & resume test, power off
> notification makes chip lifespan worse.
> So we decides that don't use this feature for our product. At that
> time, make a spec. they only consider it at power off case. but we
> implement it at suspend & resume.
> Like similarly they think the data tag seems interesting but it also
> uses the some special area at eMMC internally.
> Yes it's firmware dependent. at least. we can't measured it properly
> so we have to verify it at real condition.
> That's reason make it configurable.
>

Power OFF notification should help in improving the device lifespan.
The implementation of using power OFF notification during
suspend/resume was wrong and Girish is working on it to improve it.

The data tag does not cause any additional write which could impact
device lifetime. It should improve throughput if eMMC firmware
implements the feature. Otherwise, it should be just harmless.

But I will still take your recommendation to keep some host specific
configuration to enable any of the MMC-4.5 features.

> Kyungmin Park
>>
>> The platform data is the wrong location to indicate what are
>> essentially standards
>> driven features.
>> I am wondering already the need for CAPS2_BKOPS_SUPPORT and the like,
>> when the feature has nothing to do with the host controller.
>>
>>> and now there's no data if it enables the both, data tag, packed
>>> command or other combination, e.g., cache and so on.
>>>
>>> So I suggest make it enable/disable these features at platform data,
>>> similarly support pre-defined op by MMC_CAP_CMD23.
>>> and I saw the Saugata's active regards with Context ID.  so it's also
>>> make it configurable.
>>>
>>> Thank you,
>>> Kyungmin Park
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] MMC-4.5 Data Tag Support

2011-12-21 Thread Saugata Das
On 21 December 2011 17:01, Girish K S  wrote:
> On 21 December 2011 16:42, Saugata Das  wrote:
>> On 21 December 2011 16:23, Girish K S  
>> wrote:
>>> On 21 December 2011 13:09, Saugata Das  wrote:
>>>> From: Saugata Das 
>>>>
>>>> MMC-4.5 data tag feature will be used to store the file system meta-data 
>>>> in the
>>>> tagged region of eMMC. This will improve the write and subsequent read 
>>>> transfer
>>>> time for the meta data.
>>>>
>>>> Signed-off-by: Saugata Das 
>>>> ---
>>>>  drivers/mmc/card/block.c |   17 +++--
>>>>  drivers/mmc/core/mmc.c   |   14 ++
>>>>  include/linux/mmc/card.h |    2 ++
>>>>  include/linux/mmc/mmc.h  |    3 +++
>>>>  4 files changed, 34 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>>> index a1cb21f..af3b6c3 100644
>>>> --- a/drivers/mmc/card/block.c
>>>> +++ b/drivers/mmc/card/block.c
>>>> @@ -995,6 +995,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
>>>> *mqrq,
>>>>        struct mmc_blk_request *brq = &mqrq->brq;
>>>>        struct request *req = mqrq->req;
>>>>        struct mmc_blk_data *md = mq->data;
>>>> +       bool do_data_tag;
>>>>
>>>>        /*
>>>>         * Reliable writes are used to implement Forced Unit Access and
>>>> @@ -1071,6 +1072,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
>>>> *mqrq,
>>>>                mmc_apply_rel_rw(brq, card, req);
>>>>
>>>>        /*
>>>> +        * Data tag is used only during writing meta data to speed
>>>> +        * up write and any subsequent read of this meta data
>>>> +        */
>>>> +       do_data_tag = (card->ext_csd.data_tag_unit_size) &&
>>>> +               (req->cmd_flags & REQ_META) &&
>>>> +               (rq_data_dir(req) == WRITE) &&
>>>> +               ((brq->data.blocks * brq->data.blksz) >=
>>>> +               card->ext_csd.data_tag_unit_size) ;
>>>> +
>>>> +       /*
>>>>         * Pre-defined multi-block transfers are preferable to
>>>>         * open ended-ones (and necessary for reliable writes).
>>>>         * However, it is not sufficient to just send CMD23,
>>>> @@ -1091,10 +1102,12 @@ static void mmc_blk_rw_rq_prep(struct 
>>>> mmc_queue_req *mqrq,
>>>>
>>>>        if ((md->flags & MMC_BLK_CMD23) &&
>>>>            mmc_op_multi(brq->cmd.opcode) &&
>>>> -           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
>>>> +           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
>>>> +               do_data_tag)) {
>>>>                brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
>>>>                brq->sbc.arg = brq->data.blocks |
>>>> -                       (do_rel_wr ? (1 << 31) : 0);
>>>> +                       (do_rel_wr ? (1 << 31) : 0) |
>>>> +                       (do_data_tag ? (1 << 29) : 0);
>>>>                brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
>>>>                brq->mrq.sbc = &brq->sbc;
>>>>        }
>>>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>>>> index dbf421a..244049b 100644
>>>> --- a/drivers/mmc/core/mmc.c
>>>> +++ b/drivers/mmc/core/mmc.c
>>>> @@ -488,6 +488,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
>>>> *ext_csd)
>>>>                        ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
>>>>                        ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
>>>>                        ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
>>>> +
>>>> +               if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
>>>> +                       card->ext_csd.data_sector_size = 4096;
>>>> +               else
>>>> +                       card->ext_csd.data_sector_size = 512;
>>>> +
>>>> +               if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
>>>> +                       (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
>>>> +                       card->ext_csd.data_tag_unit_size =
>

Re: [PATCH] MMC-4.5 Data Tag Support

2011-12-21 Thread Saugata Das
On 21 December 2011 16:23, Girish K S  wrote:
> On 21 December 2011 13:09, Saugata Das  wrote:
>> From: Saugata Das 
>>
>> MMC-4.5 data tag feature will be used to store the file system meta-data in 
>> the
>> tagged region of eMMC. This will improve the write and subsequent read 
>> transfer
>> time for the meta data.
>>
>> Signed-off-by: Saugata Das 
>> ---
>>  drivers/mmc/card/block.c |   17 +++--
>>  drivers/mmc/core/mmc.c   |   14 ++
>>  include/linux/mmc/card.h |    2 ++
>>  include/linux/mmc/mmc.h  |    3 +++
>>  4 files changed, 34 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>> index a1cb21f..af3b6c3 100644
>> --- a/drivers/mmc/card/block.c
>> +++ b/drivers/mmc/card/block.c
>> @@ -995,6 +995,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
>> *mqrq,
>>        struct mmc_blk_request *brq = &mqrq->brq;
>>        struct request *req = mqrq->req;
>>        struct mmc_blk_data *md = mq->data;
>> +       bool do_data_tag;
>>
>>        /*
>>         * Reliable writes are used to implement Forced Unit Access and
>> @@ -1071,6 +1072,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
>> *mqrq,
>>                mmc_apply_rel_rw(brq, card, req);
>>
>>        /*
>> +        * Data tag is used only during writing meta data to speed
>> +        * up write and any subsequent read of this meta data
>> +        */
>> +       do_data_tag = (card->ext_csd.data_tag_unit_size) &&
>> +               (req->cmd_flags & REQ_META) &&
>> +               (rq_data_dir(req) == WRITE) &&
>> +               ((brq->data.blocks * brq->data.blksz) >=
>> +               card->ext_csd.data_tag_unit_size) ;
>> +
>> +       /*
>>         * Pre-defined multi-block transfers are preferable to
>>         * open ended-ones (and necessary for reliable writes).
>>         * However, it is not sufficient to just send CMD23,
>> @@ -1091,10 +1102,12 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
>> *mqrq,
>>
>>        if ((md->flags & MMC_BLK_CMD23) &&
>>            mmc_op_multi(brq->cmd.opcode) &&
>> -           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
>> +           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
>> +               do_data_tag)) {
>>                brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
>>                brq->sbc.arg = brq->data.blocks |
>> -                       (do_rel_wr ? (1 << 31) : 0);
>> +                       (do_rel_wr ? (1 << 31) : 0) |
>> +                       (do_data_tag ? (1 << 29) : 0);
>>                brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
>>                brq->mrq.sbc = &brq->sbc;
>>        }
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index dbf421a..244049b 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -488,6 +488,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
>> *ext_csd)
>>                        ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
>>                        ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
>>                        ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
>> +
>> +               if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
>> +                       card->ext_csd.data_sector_size = 4096;
>> +               else
>> +                       card->ext_csd.data_sector_size = 512;
>> +
>> +               if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
>> +                       (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
>> +                       card->ext_csd.data_tag_unit_size =
>> +                       ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) 
>> *
>> +                       (card->ext_csd.data_sector_size);
>> +               } else {
>> +                       card->ext_csd.data_tag_unit_size = 0;
>> +               }
>>        }
>>
>>  out:
>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>> index 415f2db..a55668d 100644
>> --- a/include/linux/mmc/card.h
>> +++ b/include/linux/mmc/card.h
>> @@ -71,6 +71,8 @@ struct mmc_ext_csd {
>>        bool                    hpi_en;                 /* HPI enablebit */
>>        bool                    hpi;                    /* HPI support bit */
>>    

[PATCH] MMC-4.5 Data Tag Support

2011-12-20 Thread Saugata Das
From: Saugata Das 

MMC-4.5 data tag feature will be used to store the file system meta-data in the
tagged region of eMMC. This will improve the write and subsequent read transfer
time for the meta data.

Signed-off-by: Saugata Das 
---
 drivers/mmc/card/block.c |   17 +++--
 drivers/mmc/core/mmc.c   |   14 ++
 include/linux/mmc/card.h |2 ++
 include/linux/mmc/mmc.h  |3 +++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a1cb21f..af3b6c3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -995,6 +995,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_blk_request *brq = &mqrq->brq;
struct request *req = mqrq->req;
struct mmc_blk_data *md = mq->data;
+   bool do_data_tag;
 
/*
 * Reliable writes are used to implement Forced Unit Access and
@@ -1071,6 +1072,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
mmc_apply_rel_rw(brq, card, req);
 
/*
+* Data tag is used only during writing meta data to speed
+* up write and any subsequent read of this meta data
+*/
+   do_data_tag = (card->ext_csd.data_tag_unit_size) &&
+   (req->cmd_flags & REQ_META) &&
+   (rq_data_dir(req) == WRITE) &&
+   ((brq->data.blocks * brq->data.blksz) >=
+   card->ext_csd.data_tag_unit_size) ;
+
+   /*
 * Pre-defined multi-block transfers are preferable to
 * open ended-ones (and necessary for reliable writes).
 * However, it is not sufficient to just send CMD23,
@@ -1091,10 +1102,12 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
 
if ((md->flags & MMC_BLK_CMD23) &&
mmc_op_multi(brq->cmd.opcode) &&
-   (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
+   (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
+   do_data_tag)) {
brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
brq->sbc.arg = brq->data.blocks |
-   (do_rel_wr ? (1 << 31) : 0);
+   (do_rel_wr ? (1 << 31) : 0) |
+   (do_data_tag ? (1 << 29) : 0);
brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
brq->mrq.sbc = &brq->sbc;
}
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index dbf421a..244049b 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -488,6 +488,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+   if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+   card->ext_csd.data_sector_size = 4096;
+   else
+   card->ext_csd.data_sector_size = 512;
+
+   if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
+   (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
+   card->ext_csd.data_tag_unit_size =
+   ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
+   (card->ext_csd.data_sector_size);
+   } else {
+   card->ext_csd.data_tag_unit_size = 0;
+   }
}
 
 out:
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 415f2db..a55668d 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -71,6 +71,8 @@ struct mmc_ext_csd {
boolhpi_en; /* HPI enablebit */
boolhpi;/* HPI support bit */
unsigned inthpi_cmd;/* cmd used as HPI */
+   unsigned intdata_sector_size;   /* 512Bytes or 4KB */
+   unsigned intdata_tag_unit_size; /* DATA TAG UNIT size */
u8  raw_partition_support;  /* 160 */
u8  raw_erased_mem_count;   /* 181 */
u8  raw_ext_csd_structure;  /* 194 */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0e71356..e076f7f 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -273,6 +273,7 @@ struct _mmc_csd {
 #define EXT_CSD_FLUSH_CACHE32  /* W */
 #define EXT_CSD_CACHE_CTRL 33  /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION 34  /* R/W */
+#define EXT_CSD_DATA_SECTOR_SIZE   61  /* R */
 #define EXT_CSD_GP_SIZE_MULT   143 /* R/W */
 #define EXT_CSD_PARTITIO

Re: [PATCH V2] mmc: core: Add host capability check for power class

2011-12-15 Thread Saugata Das
On 15 December 2011 16:22, Girish K S  wrote:
> On 15 December 2011 15:34, Saugata Das  wrote:
>> On 15 December 2011 09:28, Girish K S  
>> wrote:
>>> This patch adds a check whether the host supports maximum current value
>>> obtained from the device's extended csd register for a selected interface
>>> voltage and frequency.
>>>
>>> cc: Chris Ball 
>>> Signed-off-by: Girish K S 
>>> ---
>>> Changes in v2:
>>>        deleted a unnecessary if else condition identified by subhash J
>>> Changes in v1:
>>>       reduced the number of comparisons as per Hein's suggestion
>>>
>>>  drivers/mmc/core/mmc.c   |   19 +++
>>>  include/linux/mmc/card.h |    4 
>>>  2 files changed, 23 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>>> index 006e932..b9ef777 100644
>>> --- a/drivers/mmc/core/mmc.c
>>> +++ b/drivers/mmc/core/mmc.c
>>> @@ -688,6 +688,25 @@ static int mmc_select_powerclass(struct mmc_card *card,
>>>                pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >>
>>>                                EXT_CSD_PWR_CL_4BIT_SHIFT;
>>>
>>> +       if (pwrclass_val >= MMC_MAX_CURRENT_800)
>>> +               pwrclass_val = MMC_MAX_CURRENT_800;
>>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_600)
>>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_400)
>>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>>> +       else
>>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>>> +
>>> +       if ((pwrclass_val == MMC_MAX_CURRENT_800) &&
>>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_800))
>>> +               pwrclass_val = MMC_MAX_CURRENT_600;
>>> +       if ((pwrclass_val == MMC_MAX_CURRENT_600) &&
>>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_600))
>>> +               pwrclass_val = MMC_MAX_CURRENT_400;
>>> +       if ((pwrclass_val == MMC_MAX_CURRENT_400) &&
>>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_400))
>>> +               pwrclass_val = MMC_MAX_CURRENT_200;
>>> +
>>>        /* If the power class is different from the default value */
>>>        if (pwrclass_val > 0) {
>>>                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>
>> It is not allowed to set the POWER_CLASS with any value other than
>> what is mentioned in the PWR_CL_ff_vvv or PWR_CL_DDR_ff_vvv  for the
>> corresponding frequency, voltage. That is, if PWR_CL_200_195 is 14 and
>> we want to operate at HS200 then the only value allowed for
>> POWER_CLASS is 14. So, we need to check the PWR_CL numbers and choose
>> the operating mode (HS200/DDR50/..) based on the platform capability
>> to support the current consumption and set the corresponding
>> POWER_CLASS value.
>>
>> Please refer to section 6.6.5 of the 4.5 spec.
>
> The upstreamed code reads the extended csd value based on the already
> set voltage level and frequency of host. So it will get the required
> power class value which can be set directly. Is my understanding
> correct?
>

It is not enough to just check the voltage level and frequency.
Consider this example, host has capability to support
MMC_CAP_MAX_CURRENT_400, the PWR_CL_DDR_52_360 has the value 9 (400mA)
and PWR_CL_200_360 has the value 14 (800mA). Then even though the host
might be capable to run 200MHz clock and 3.6V, it can only enable DDR
at 52MHz and set 9 in POWER_CLASS.

I think, in mmc_select_powerclass, we need to loop through the power
classes of all supported modes of transfer (HS200, DDR52, ... ) and
choose the mode which gives maximum bandwidth but falls within host
capability of current consumption. Then set this to POWER_CLASS byte
and also use the same information when setting HS_TIMING in
mmc_init_card.

>>
>>
>>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>>> index 9478a6b..c5e031a 100644
>>> --- a/include/linux/mmc/card.h
>>> +++ b/include/linux/mmc/card.h
>>> @@ -195,6 +195,10 @@ struct mmc_part {
>>>  #define MMC_BLK_DATA_AREA_GP   (1<<2)
>>>  };
>>>
>>> +#define MMC_MAX_CURRENT_200    (0)
>>> +#define MMC_MAX_CURRENT_400    (7)
>>> +#define MMC_MAX_CURRENT_600    (11)
>>> +#define MMC_MAX_CURRENT_800    (13)
>>>  /*
>>>  * MMC device
>>>  */
>>> --
>>> 1.7.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majord...@vger.kernel.org
>>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Cache Control during mmc_suspend_host

2011-12-15 Thread Saugata Das
On 14 December 2011 10:04, Seungwon Jeon  wrote:
> Saugata Das wrote:
>> On 13 December 2011 11:57, Seungwon Jeon  wrote:
>> > Hi Saugata,
>> >
>> > Saugata Das wrote:
>> >> Hi Seungwon Jeon
>> >>
>> >> I see a small issue with the implementation mmc_suspend_host,
>> >>
>> >> int mmc_suspend_host(struct mmc_host *host)
>> >> {
>> >> .
>> >>       err = mmc_cache_ctrl(host, 0);
>> >> }
>> >>
>> >> So, within mmc_suspend_host we are disabling the cache. But I do not
>> >> see a corresponding enabling of cache within mmc_resume_host. I
>> >> suggest we have either enabling of cache within mmc_resume_host or
>> >> within mmc_suspend_host, we replace mmc_cache_ctrl(host, 0) with the
>> >> flush operation, mmc_flush_cache(host->card).
>> >>
>> > Currently,
>> > Cache is enabled in mmc_init_card() during mmc_resume_host().
>> >
>> Thanks for your answer.
>>
>> If mmc_card_keep_power is TRUE, then do you know why from mmc_resume
>> we call mmc_init_card instead of just mmc_awake which should reduce
>> some latency of system wakeup ?
>>
> I didn't find that case of keeping the power
> during sleep in mmc unlike sdio.

I am talking about keeping VCCQ ON and switching OFF only VCC. This is
normally the SLEEP mode of eMMC, which provides quicker wakeup or
resume. Some platforms will like to have quicker resume and will like
to avoid doing a mmc_init_card during resume. If that happens, then
the cache control disabling from mmc_suspend_host will be a problem.
So, I suggest we change that to mmc_flush_cache which logically does
the same as  you wanted but it is also future proof.

>
>>
>> > Thanks,
>> > Seungwon Jeon.
>> >>
>> >>
>> >> Regards
>> >> Saugata
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> >> the body of a message to majord...@vger.kernel.org
>> >> 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 majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] mmc: core: Add host capability check for power class

2011-12-15 Thread Saugata Das
On 15 December 2011 09:28, Girish K S  wrote:
> This patch adds a check whether the host supports maximum current value
> obtained from the device's extended csd register for a selected interface
> voltage and frequency.
>
> cc: Chris Ball 
> Signed-off-by: Girish K S 
> ---
> Changes in v2:
>        deleted a unnecessary if else condition identified by subhash J
> Changes in v1:
>       reduced the number of comparisons as per Hein's suggestion
>
>  drivers/mmc/core/mmc.c   |   19 +++
>  include/linux/mmc/card.h |    4 
>  2 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 006e932..b9ef777 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -688,6 +688,25 @@ static int mmc_select_powerclass(struct mmc_card *card,
>                pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >>
>                                EXT_CSD_PWR_CL_4BIT_SHIFT;
>
> +       if (pwrclass_val >= MMC_MAX_CURRENT_800)
> +               pwrclass_val = MMC_MAX_CURRENT_800;
> +       else if (pwrclass_val >= MMC_MAX_CURRENT_600)
> +               pwrclass_val = MMC_MAX_CURRENT_600;
> +       else if (pwrclass_val >= MMC_MAX_CURRENT_400)
> +               pwrclass_val = MMC_MAX_CURRENT_400;
> +       else
> +               pwrclass_val = MMC_MAX_CURRENT_200;
> +
> +       if ((pwrclass_val == MMC_MAX_CURRENT_800) &&
> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_800))
> +               pwrclass_val = MMC_MAX_CURRENT_600;
> +       if ((pwrclass_val == MMC_MAX_CURRENT_600) &&
> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_600))
> +               pwrclass_val = MMC_MAX_CURRENT_400;
> +       if ((pwrclass_val == MMC_MAX_CURRENT_400) &&
> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_400))
> +               pwrclass_val = MMC_MAX_CURRENT_200;
> +
>        /* If the power class is different from the default value */
>        if (pwrclass_val > 0) {
>                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,

It is not allowed to set the POWER_CLASS with any value other than
what is mentioned in the PWR_CL_ff_vvv or PWR_CL_DDR_ff_vvv  for the
corresponding frequency, voltage. That is, if PWR_CL_200_195 is 14 and
we want to operate at HS200 then the only value allowed for
POWER_CLASS is 14. So, we need to check the PWR_CL numbers and choose
the operating mode (HS200/DDR50/..) based on the platform capability
to support the current consumption and set the corresponding
POWER_CLASS value.

Please refer to section 6.6.5 of the 4.5 spec.


> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 9478a6b..c5e031a 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -195,6 +195,10 @@ struct mmc_part {
>  #define MMC_BLK_DATA_AREA_GP   (1<<2)
>  };
>
> +#define MMC_MAX_CURRENT_200    (0)
> +#define MMC_MAX_CURRENT_400    (7)
> +#define MMC_MAX_CURRENT_600    (11)
> +#define MMC_MAX_CURRENT_800    (13)
>  /*
>  * MMC device
>  */
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Cache Control during mmc_suspend_host

2011-12-13 Thread Saugata Das
On 13 December 2011 11:57, Seungwon Jeon  wrote:
> Hi Saugata,
>
> Saugata Das wrote:
>> Hi Seungwon Jeon
>>
>> I see a small issue with the implementation mmc_suspend_host,
>>
>> int mmc_suspend_host(struct mmc_host *host)
>> {
>> .
>>       err = mmc_cache_ctrl(host, 0);
>> }
>>
>> So, within mmc_suspend_host we are disabling the cache. But I do not
>> see a corresponding enabling of cache within mmc_resume_host. I
>> suggest we have either enabling of cache within mmc_resume_host or
>> within mmc_suspend_host, we replace mmc_cache_ctrl(host, 0) with the
>> flush operation, mmc_flush_cache(host->card).
>>
> Currently,
> Cache is enabled in mmc_init_card() during mmc_resume_host().
>
Thanks for your answer.

If mmc_card_keep_power is TRUE, then do you know why from mmc_resume
we call mmc_init_card instead of just mmc_awake which should reduce
some latency of system wakeup ?


> Thanks,
> Seungwon Jeon.
>>
>>
>> Regards
>> Saugata
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majord...@vger.kernel.org
>> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5

2011-12-12 Thread Saugata Das
On 13 December 2011 10:13, Girish K S  wrote:
> On 12 December 2011 12:20, Girish K S  wrote:
>> On 5 December 2011 20:29, Saugata Das  wrote:
>>> Hi Girish
>>>
>>> Please refer to Figure 71 (HS200 device output timing) of the MMC-4.5
>>> spec. It shows that both CMD and DATA[7-0] will have some latency till
>>> valid window. This implies that even the CMD line will need tuning for
>>> reading the response. The specification talks about identifying
>>> sampling point for data lines by reading tuning blocks. Based on host
>>> controller capability, even the CMD line will get the good sample
>>> point during the same tuning sequence.
>>>
>>> We need to have the tuning done (execute_tuning) soon after switching
>>> to HS200 mode and 200MHz clock.
>>>
>> If i make a change as per subhash suggestion"set bus width before
>> setting the HS200 mode." then it will affect the entire frame work of
>> mmc which is developed as per Annexure A6.1 A.6.2 A.6.3 (mentions the
>> steps for bus initialization). can any of you suggest a way to do
>> this.

Note that, we need to make this modification only for HS200 mode. For
DDR mode, it is required that we keep the current way (i.e. setting
BUS_WIDTH after HS_TIMING).

>
> Any inputs on this
>
>>>
>>> Regards
>>> Saugata
>>>
>>>
>>> On 5 December 2011 16:59, Subhash Jadavani  wrote:
>>>>
>>>>
>>>>> -Original Message-
>>>>> From: Girish K S [mailto:girish.shivananja...@linaro.org]
>>>>> Sent: Monday, December 05, 2011 12:20 PM
>>>>> To: Subhash Jadavani
>>>>> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>>>>> s...@vger.kernel.org; Chris Ball
>>>>> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5
>>>>>
>>>>> On 5 December 2011 11:46, Subhash Jadavani 
>>>>> wrote:
>>>>> >
>>>>> >
>>>>> >> -Original Message-
>>>>> >> From: Girish K S [mailto:girish.shivananja...@linaro.org]
>>>>> >> Sent: Friday, December 02, 2011 5:08 PM
>>>>> >> To: Subhash Jadavani
>>>>> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>>>>> >> s...@vger.kernel.org; Chris Ball
>>>>> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5
>>>>> >>
>>>>> >> On 2 December 2011 00:02, Subhash Jadavani 
>>>>> >> wrote:
>>>>> >> >
>>>>> >> >
>>>>> >> >> -Original Message-
>>>>> >> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>>>>> >> >> ow...@vger.kernel.org] On Behalf Of Girish K S
>>>>> >> >> Sent: Thursday, December 01, 2011 7:48 PM
>>>>> >> >> To: Subhash Jadavani
>>>>> >> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>>>>> >> >> s...@vger.kernel.org; Chris Ball
>>>>> >> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC
>>>>> 4.5
>>>>> >> >>
>>>>> >> >> On 1 December 2011 16:27, Subhash Jadavani
>>>>> 
>>>>> >> >> wrote:
>>>>> >> >> >
>>>>> >> >> >
>>>>> >> >> >> -Original Message-
>>>>> >> >> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>>>>> >> >> >> ow...@vger.kernel.org] On Behalf Of Girish K S
>>>>> >> >> >> Sent: Thursday, December 01, 2011 3:58 PM
>>>>> >> >> >> To: Subhash Jadavani
>>>>> >> >> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-
>>>>> samsung-
>>>>> >> >> >> s...@vger.kernel.org; Chris Ball
>>>>> >> >> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC
>>>>> >> 4.5
>>>>> >> >> >>
>>>>> >> >> >> On 1 December 2011 15:33, Subhash Jadavani
>>>>> >> 
>>>>> >> >> >> wrote:
>>>>> >> >> &g

Cache Control during mmc_suspend_host

2011-12-12 Thread Saugata Das
Hi Seungwon Jeon

I see a small issue with the implementation mmc_suspend_host,

int mmc_suspend_host(struct mmc_host *host)
{
.
err = mmc_cache_ctrl(host, 0);
}

So, within mmc_suspend_host we are disabling the cache. But I do not
see a corresponding enabling of cache within mmc_resume_host. I
suggest we have either enabling of cache within mmc_resume_host or
within mmc_suspend_host, we replace mmc_cache_ctrl(host, 0) with the
flush operation, mmc_flush_cache(host->card).



Regards
Saugata
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5

2011-12-05 Thread Saugata Das
Hi Girish

Please refer to Figure 71 (HS200 device output timing) of the MMC-4.5
spec. It shows that both CMD and DATA[7-0] will have some latency till
valid window. This implies that even the CMD line will need tuning for
reading the response. The specification talks about identifying
sampling point for data lines by reading tuning blocks. Based on host
controller capability, even the CMD line will get the good sample
point during the same tuning sequence.

We need to have the tuning done (execute_tuning) soon after switching
to HS200 mode and 200MHz clock.


Regards
Saugata


On 5 December 2011 16:59, Subhash Jadavani  wrote:
>
>
>> -Original Message-
>> From: Girish K S [mailto:girish.shivananja...@linaro.org]
>> Sent: Monday, December 05, 2011 12:20 PM
>> To: Subhash Jadavani
>> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>> s...@vger.kernel.org; Chris Ball
>> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5
>>
>> On 5 December 2011 11:46, Subhash Jadavani 
>> wrote:
>> >
>> >
>> >> -Original Message-
>> >> From: Girish K S [mailto:girish.shivananja...@linaro.org]
>> >> Sent: Friday, December 02, 2011 5:08 PM
>> >> To: Subhash Jadavani
>> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>> >> s...@vger.kernel.org; Chris Ball
>> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5
>> >>
>> >> On 2 December 2011 00:02, Subhash Jadavani 
>> >> wrote:
>> >> >
>> >> >
>> >> >> -Original Message-
>> >> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> >> >> ow...@vger.kernel.org] On Behalf Of Girish K S
>> >> >> Sent: Thursday, December 01, 2011 7:48 PM
>> >> >> To: Subhash Jadavani
>> >> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-samsung-
>> >> >> s...@vger.kernel.org; Chris Ball
>> >> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC
>> 4.5
>> >> >>
>> >> >> On 1 December 2011 16:27, Subhash Jadavani
>> 
>> >> >> wrote:
>> >> >> >
>> >> >> >
>> >> >> >> -Original Message-
>> >> >> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> >> >> >> ow...@vger.kernel.org] On Behalf Of Girish K S
>> >> >> >> Sent: Thursday, December 01, 2011 3:58 PM
>> >> >> >> To: Subhash Jadavani
>> >> >> >> Cc: linux-mmc@vger.kernel.org; patc...@linaro.org; linux-
>> samsung-
>> >> >> >> s...@vger.kernel.org; Chris Ball
>> >> >> >> Subject: Re: [PATCH V5] mmc: core: HS200 mode support for eMMC
>> >> 4.5
>> >> >> >>
>> >> >> >> On 1 December 2011 15:33, Subhash Jadavani
>> >> 
>> >> >> >> wrote:
>> >> >> >> > Hi Girish,
>> >> >> >> >
>> >> >> >> >> -Original Message-
>> >> >> >> >> From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
>> >> >> >> >> ow...@vger.kernel.org] On Behalf Of Girish K S
>> >> >> >> >> Sent: Wednesday, November 30, 2011 2:24 PM
>> >> >> >> >> To: linux-mmc@vger.kernel.org
>> >> >> >> >> Cc: patc...@linaro.org; linux-samsung-...@vger.kernel.org;
>> >> >> >> >> subha...@codeaurora.org; Girish K S; Chris Ball
>> >> >> >> >> Subject: [PATCH V5] mmc: core: HS200 mode support for eMMC
>> 4.5
>> >> >> >> >>
>> >> >> >> >> This patch adds the support of the HS200 bus speed for eMMC
>> >> 4.5
>> >> >> >> >> devices.
>> >> >> >> >> The eMMC 4.5 devices have support for 200MHz bus speed.The
>> mmc
>> >> >> core
>> >> >> >> and
>> >> >> >> >> host modules have been touched to add support for this
>> module.
>> >> >> >> >>
>> >> >> >> >> It is necessary to know the card type in the sdhci.c file
>> to
>> >> add
>> >> >> >> >> support
>> >> >> >> >> for eMMC tuning function. So card.h file is included to
>> import
>> >> >> the
>> >> >> >> card
>> >> >> >> >> data structure.
>> >> >> >> >>
>> >> >> >> >> cc: Chris Ball 
>> >> >> >> >> Signed-off-by: Girish K S 
>> >> >> >> >> ---
>> >> >> >> >> Changes in v5:
>> >> >> >> >>       Reduced the case statements for better code
>> readability.
>> >> >> >> Removed
>> >> >> >> >>       unused macro definitions. Modified the tuning
>> function
>> >> >> >> prototype
>> >> >> >> >>       and definition to support tuning for both SD and eMMC
>> >> >> cards.
>> >> >> >> >> Changes in v4:
>> >> >> >> >>       Rebased onto chris-mmc/mmc-next branch. This patch is
>> >> >> >> >> successfully
>> >> >> >> >>       applied on commit with id
>> >> >> >> >> de022ed3fdc14808299b2fa66dbb1ed5ab921912.
>> >> >> >> >> Changes in v3:
>> >> >> >> >>       In the previous commits of chris-mmc/mmc-next branch,
>> >> the
>> >> >> >> patch
>> >> >> >> >> with
>> >> >> >> >>       commit id (c0f22a2c92e357e7cb3988b0b13034d70b7461f9)
>> >> >> defines
>> >> >> >> >> caps2 for
>> >> >> >> >>       more capabilities. This patch version deletes the
>> member
>> >> >> >> >> ext_caps(created
>> >> >> >> >>       in my earlier patch) from struct mmc_host and reuses
>> >> >> already
>> >> >> >> >> accepted
>> >> >> >> >>       caps2 member.
>> >> >> >> >> Changes in v2:
>> >> >> >> >>       Rebased to latest chris-mmc/mmc-next branch. Res