Re: [PATCH] mmc: core: Do not poll for busy with status cmd for all switch cmds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Chris,

Ping.

Kind regards
Ulf Hansson


On 12 September 2013 04:41, Jaehoon Chung <jh80.chung@xxxxxxxxxxx> wrote:
> Hi Ulf,
>
> I will test with this patch, and share the result.
> Thanks for posting this patch.
>
> Best Regards,
> Jaehoon Chung
>
> On 09/11/2013 06:54 PM, Ulf Hansson wrote:
>> Some switch operations like poweroff notify, shall according to the
>> spec not be followed by any other new commands. For these cases and
>> when the host does'nt support MMC_CAP_WAIT_WHILE_BUSY, we must not
>> send status commands to poll for busy detection. Instead wait for
>> the stated timeout from the EXT_CSD before completing the request.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx>
>> Cc: Jaehoon Chung <jh80.chung@xxxxxxxxxxx>
>> ---
>>  drivers/mmc/core/core.c    |    2 +-
>>  drivers/mmc/core/mmc.c     |    6 +++---
>>  drivers/mmc/core/mmc_ops.c |   23 ++++++++++++++++++-----
>>  include/linux/mmc/core.h   |    3 ++-
>>  4 files changed, 24 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index b9b9fb6..15eba0c 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -301,7 +301,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
>>       }
>>
>>       err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                     EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
>> +                     EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal, true);
>>       if (err) {
>>               pr_warn("%s: Error %d starting bkops\n",
>>                       mmc_hostname(card->host), err);
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index 6d02012..8f0c516 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -1404,9 +1404,9 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
>>       if (notify_type == EXT_CSD_POWER_OFF_LONG)
>>               timeout = card->ext_csd.power_off_longtime;
>>
>> -     err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                      EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                      notify_type, timeout);
>> +     err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                     EXT_CSD_POWER_OFF_NOTIFICATION,
>> +                     notify_type, timeout, true, false);
>>       if (err)
>>               pr_err("%s: Power Off Notification timed out, %u\n",
>>                      mmc_hostname(card->host), timeout);
>> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
>> index ef18348..5ea83b6 100644
>> --- a/drivers/mmc/core/mmc_ops.c
>> +++ b/drivers/mmc/core/mmc_ops.c
>> @@ -370,11 +370,12 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
>>   *   @timeout_ms: timeout (ms) for operation performed by register write,
>>   *                   timeout of zero implies maximum possible timeout
>>   *   @use_busy_signal: use the busy signal as response type
>> + *   @send_status: send status cmd to poll for busy
>>   *
>>   *   Modifies the EXT_CSD register for selected card.
>>   */
>>  int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
>> -            unsigned int timeout_ms, bool use_busy_signal)
>> +             unsigned int timeout_ms, bool use_busy_signal, bool send_status)
>>  {
>>       int err;
>>       struct mmc_command cmd = {0};
>> @@ -411,14 +412,26 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
>>       /* Must check status to be sure of no errors */
>>       timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
>>       do {
>> -             err = mmc_send_status(card, &status);
>> -             if (err)
>> -                     return err;
>> +             if (send_status) {
>> +                     err = mmc_send_status(card, &status);
>> +                     if (err)
>> +                             return err;
>> +             }
>>               if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
>>                       break;
>>               if (mmc_host_is_spi(card->host))
>>                       break;
>>
>> +             /*
>> +              * We are not allowed to issue a status command and the host
>> +              * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only
>> +              * rely on waiting for the stated timeout to be sufficient.
>> +              */
>> +             if (!send_status) {
>> +                     mmc_delay(timeout_ms);
>> +                     return 0;
>> +             }
>> +
>>               /* Timeout if the device never leaves the program state. */
>>               if (time_after(jiffies, timeout)) {
>>                       pr_err("%s: Card stuck in programming state! %s\n",
>> @@ -445,7 +458,7 @@ EXPORT_SYMBOL_GPL(__mmc_switch);
>>  int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
>>               unsigned int timeout_ms)
>>  {
>> -     return __mmc_switch(card, set, index, value, timeout_ms, true);
>> +     return __mmc_switch(card, set, index, value, timeout_ms, true, true);
>>  }
>>  EXPORT_SYMBOL_GPL(mmc_switch);
>>
>> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
>> index da51bec..64274ec 100644
>> --- a/include/linux/mmc/core.h
>> +++ b/include/linux/mmc/core.h
>> @@ -151,7 +151,8 @@ extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
>>  extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
>>       struct mmc_command *, int);
>>  extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
>> -extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
>> +extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
>> +                     bool);
>>  extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
>>  extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux