RE: [patchv3 2/4] MMC: SDHCI R1B command handling + MMC_CAP_ERASE.

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

 




> -----Original Message-----
> From: linux-mmc-owner@xxxxxxxxxxxxxxx
> [mailto:linux-mmc-owner@xxxxxxxxxxxxxxx] On Behalf Of Andrei Warkentin
> Sent: Tuesday, April 12, 2011 5:14 AM
> To: linux-mmc@xxxxxxxxxxxxxxx
> Cc: arnd@xxxxxxxx; cjb@xxxxxxxxxx; Andrei Warkentin
> Subject: [patchv3 2/4] MMC: SDHCI R1B command handling + MMC_CAP_ERASE.
> 
> ERASE command needs R1B response, so fix R1B-type command
> handling for SDHCI controller. For non-DAT commands using a busy
> reponse, the cmd->cmd_timeout_ms (in ms) field is used for timeout
> calculations.
> 
> Based on patch by Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx>
> Signed-off-by: Andrei Warkentin <andreiw@xxxxxxxxxxxx>
> ---
>  drivers/mmc/host/sdhci.c |   43 +++++++++++++++++++++++++++----------------
>  1 files changed, 27 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 9e15f41..173e980 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -40,7 +40,6 @@
> 
>  static unsigned int debug_quirks = 0;
> 
> -static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
>  static void sdhci_finish_data(struct sdhci_host *);
> 
>  static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
> @@ -591,9 +590,10 @@ static void sdhci_adma_table_post(struct sdhci_host
> *host,
>  		data->sg_len, direction);
>  }
> 
> -static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
> +static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command
> *cmd)
>  {
>  	u8 count;
> +	struct mmc_data *data = cmd->data;
>  	unsigned target_timeout, current_timeout;
> 
>  	/*
> @@ -605,12 +605,16 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host,
> struct mmc_data *data)
>  	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
>  		return 0xE;
> 
> -	/* timeout in us */
> -	target_timeout = data->timeout_ns / 1000 +
> -		data->timeout_clks / host->clock;
> +	/* Unspecified timeout, assume max */
> +	if (!data && !cmd->cmd_timeout_ms)
> +		return 0xE;
Just a inline question here. I noticed cmd_timeout_ms only be set for the ERASE command and SWITCH command, for other types of commands, this value is left not initialized. Cmd_timeout_ms may not be zero and also not be initialized. And next, driver will use this value to calculate the timeout. So I think using an uninitialized value here doesn't make sense. If we want to use it, we have to make sure at this point, this value is already initialized.

> 
> -	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
> -		host->timeout_clk = host->clock / 1000;
> +	/* timeout in us */
> +	if (!data)
> +		target_timeout = cmd->cmd_timeout_ms * 1000;
That is where I concerned about the uninitialized cmd_timeout_ms.

> +	else
> +		target_timeout = data->timeout_ns / 1000 +
> +			data->timeout_clks / host->clock;
> 
>  	/*
>  	 * Figure out needed cycles.
> @@ -632,8 +636,9 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host,
> struct mmc_data *data)
>  	}
> 
>  	if (count >= 0xF) {
> -		printk(KERN_WARNING "%s: Too large timeout requested!\n",
> -			mmc_hostname(host->mmc));
> +		printk(KERN_WARNING "%s: Too large timeout requested for
> CMD%d!\n",
> +		       mmc_hostname(host->mmc),
> +		       cmd->opcode);
>  		count = 0xE;
>  	}
> 
> @@ -651,15 +656,21 @@ static void sdhci_set_transfer_irqs(struct sdhci_host
> *host)
>  		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
>  }
> 
> -static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
> +static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command
> *cmd)
>  {
>  	u8 count;
>  	u8 ctrl;
> +	struct mmc_data *data = cmd->data;
>  	int ret;
> 
>  	WARN_ON(host->data);
> 
> -	if (data == NULL)
> +	if (data || (cmd->flags & MMC_RSP_BUSY)) {
> +		count = sdhci_calc_timeout(host, cmd);
> +		sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
> +	}
> +
> +	if (!data)
>  		return;
> 
>  	/* Sanity checks */
> @@ -670,9 +681,6 @@ static void sdhci_prepare_data(struct sdhci_host *host,
> struct mmc_data *data)
>  	host->data = data;
>  	host->data_early = 0;
> 
> -	count = sdhci_calc_timeout(host, data);
> -	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
> -
>  	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
>  		host->flags |= SDHCI_REQ_USE_DMA;
> 
> @@ -920,7 +928,7 @@ static void sdhci_send_command(struct sdhci_host *host,
> struct mmc_command *cmd)
> 
>  	host->cmd = cmd;
> 
> -	sdhci_prepare_data(host, cmd->data);
> +	sdhci_prepare_data(host, cmd);
> 
>  	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
> 
> @@ -1867,6 +1875,9 @@ int sdhci_add_host(struct sdhci_host *host)
>  	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
>  		host->timeout_clk *= 1000;
> 
> +	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
> +		host->timeout_clk = host->clock / 1000;
> +
>  	/*
>  	 * Set host parameters.
>  	 */
> @@ -1879,7 +1890,7 @@ int sdhci_add_host(struct sdhci_host *host)
>  		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
> 
>  	mmc->f_max = host->max_clk;
> -	mmc->caps |= MMC_CAP_SDIO_IRQ;
> +	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE;
> 
>  	/*
>  	 * A controller may support 8-bit width, but the board itself
> --
> 1.7.0.4
> 
> --
> 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
--
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