Re: [PATCH 1/5] mmc:core: Add restrictions for data transfer and card ease

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

 



Hi, all

Could any one help review this patch set for me?

Thanks in advance.

于 2013/9/24 16:12, Haijun Zhang 写道:
> At 50 Mhz SD_CLK period,
> the max timeout value = 2^27 * SD_CLK period ~= 2.69 sec.
>
> If max_discard_to was not designed, for mmc card preferred erase
> size should be used, for sd card just return UINT_MAX. Also add
> limit for data transfer, Use max_discard_to as max data timeout value
> to avoid timeout error in case data timeout was larger than
> 2.69 sec.
>
> For some crappy cards, the timeout value calculate from card was
> larger than UINT_MAX, in this case the timeout value write into
> register was not expected.
>
> This patch can reduce I/O error due to large timeout value for
> erase(CMD38) and write(CMD25) for some crappy cards.
>
> Signed-off-by: Haijun Zhang <haijun.zhang@xxxxxxxxxxxxx>
> ---
>  drivers/mmc/core/core.c | 45 ++++++++++++++++++++++++++++++---------------
>  1 file changed, 30 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index bf18b6b..b429baa 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -757,6 +757,7 @@ EXPORT_SYMBOL(mmc_read_bkops_status);
>   */
>  void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
>  {
> +	struct mmc_host *host = card->host;
>  	unsigned int mult;
>  
>  	/*
> @@ -780,7 +781,12 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
>  	if (data->flags & MMC_DATA_WRITE)
>  		mult <<= card->csd.r2w_factor;
>  
> -	data->timeout_ns = card->csd.tacc_ns * mult;
> +	/* Avoid over flow for some crappy cards. */
> +	if ((UINT_MAX / mult) < card->csd.tacc_ns)
> +		data->timeout_ns = UINT_MAX;
> +	else
> +		data->timeout_ns = card->csd.tacc_ns * mult;
> +
>  	data->timeout_clks = card->csd.tacc_clks * mult;
>  
>  	/*
> @@ -842,6 +848,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
>  				data->timeout_ns =  100000000;	/* 100ms */
>  		}
>  	}
> +
> +	if (host->max_discard_to &&
> +			(host->max_discard_to <
> +			 (data->timeout_ns / 1000000)))
> +		data->timeout_ns = host->max_discard_to * 1000000;
>  }
>  EXPORT_SYMBOL(mmc_set_data_timeout);
>  
> @@ -1816,11 +1827,14 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
>  		unsigned int timeout_clks = card->csd.tacc_clks * mult;
>  		unsigned int timeout_us;
>  
> -		/* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */
> -		if (card->csd.tacc_ns < 1000000)
> -			timeout_us = (card->csd.tacc_ns * mult) / 1000;
> -		else
> +		/*
> +		 * Avoid over flow for some crappy cards.
> +		 * e.g. tacc_ns=80000000 mult=1280
> +		 */
> +		if ((UINT_MAX / mult) < card->csd.tacc_ns)
>  			timeout_us = (card->csd.tacc_ns / 1000) * mult;
> +		else
> +			timeout_us = (card->csd.tacc_ns * mult) / 1000;
>  
>  		/*
>  		 * ios.clock is only a target.  The real clock rate might be
> @@ -2185,16 +2199,17 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
>  	struct mmc_host *host = card->host;
>  	unsigned int max_discard, max_trim;
>  
> -	if (!host->max_discard_to)
> -		return UINT_MAX;
> -
> -	/*
> -	 * Without erase_group_def set, MMC erase timeout depends on clock
> -	 * frequence which can change.  In that case, the best choice is
> -	 * just the preferred erase size.
> -	 */
> -	if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
> -		return card->pref_erase;
> +	if (!host->max_discard_to) {
> +		/*
> +		 * Without erase_group_def set, MMC erase timeout depends
> +		 * on clock frequence which can change.  In that case, the
> +		 * best choice is just the preferred erase size.
> +		 */
> +		if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
> +			return card->pref_erase;
> +		else
> +			return UINT_MAX;
> +	}
>  
>  	max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG);
>  	if (mmc_can_trim(card)) {

-- 
Thanks & Regards
Haijun.


--
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