On 09/13/2011 06:22 AM, Chris Ball wrote:
> Hi Jeremy,
>
> On Mon, Sep 12 2011, Jeremy Fitzhardinge wrote:
>> Since 2.6.39, the SD card slot in my Lenovo X220 has stopped working.  
>> When I insert a card with current linux.git kernel (3.1-rc6), I get:
>>
>> [ 3891.745549] mmc0: new SDHC card at address b368
>> [ 3891.790704] mmcblk0: mmc0:b368 PNY   7.51 GiB 
>> [ 3891.795568] mmc0: Got data interrupt 0x00200000 even though no data
>> operation was in progress.
> Please could you try reverting a3c7778f8153b9 "mmc: sdhci: R1B command
> handling + MMC_CAP_ERASE"?  We've had one other similar report that
> bisected to this patch.
>

The revert was not entirely trivial (below), but I'm fairly sure I got
it right, and it didn't help.

On card insert, it now says:

[56549.455385] mmc0: new SDHC card at address b368
[56549.456872] mmcblk0: mmc0:b368 PNY   7.51 GiB 
[56549.467279] mmc0: starting CMD18 arg 00000000 flags 000000b5
[56549.467288] mmc0:     blksz 512 blocks 8 flags 00000200 tsac 100 ms nsac 0
[56549.467294] mmc0:     CMD12 arg 00000000 flags 0000049d
[56549.467340] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00018000
[56549.467369] mmc0: req done (CMD18): -110: 00000000 00000000 00000000 00000000
[56549.467376] mmc0:     0 bytes transferred: 0
[56549.467382] mmc0:     (CMD12): 0: 00000000 00000000 00000000 00000000
[56549.467404] mmc0: starting CMD13 arg b3680000 flags 00000195
[56549.467440] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00018000
[56549.467455] mmc0: req done (CMD13): -110: 00000000 00000000 00000000 00000000
[56549.467458] mmcblk0: error -110 sending status command, retrying
[56549.467461] mmc0: starting CMD13 arg b3680000 flags 00000195
[56549.467477] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.467484] mmc0: req done (CMD13): 0: 00800900 00000000 00000000 00000000
[56549.467488] mmcblk0: timed out sending r/w cmd command, card status 0x800900
[56549.467492] mmc0: starting CMD18 arg 00000000 flags 000000b5
[56549.467494] mmc0:     blksz 512 blocks 8 flags 00000200 tsac 100 ms nsac 0
[56549.467496] mmc0:     CMD12 arg 00000000 flags 0000049d
[56549.467518] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.467973] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00608000
[56549.468019] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00408003
[56549.468035] mmc0: req done (CMD18): 0: 00000900 00000000 00000000 00000000
[56549.468037] mmc0:     0 bytes transferred: -84
[56549.468038] mmc0:     (CMD12): 0: 00000b00 00000000 00000000 00000000
[56549.468045] mmcblk0: error -84 transferring data, sector 0, nr 8, cmd 
response 0x900, card status 0xb00
[56549.468047] mmcblk0: retrying using single block read
[56549.468051] mmc0: starting CMD17 arg 00000000 flags 000000b5
[56549.468053] mmc0:     blksz 512 blocks 1 flags 00000200 tsac 100 ms nsac 0
[56549.468076] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.468411] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00608002
[56549.468438] mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
[56549.468444] mmc0:     0 bytes transferred: -84
[56549.468459] mmcblk0: error -84 transferring data, sector 0, nr 8, cmd 
response 0x900, card status 0x0
[56549.468471] end_request: I/O error, dev mmcblk0, sector 0
[56549.468481] mmc0: starting CMD17 arg 00000001 flags 000000b5
[56549.468488] mmc0:     blksz 512 blocks 1 flags 00000200 tsac 100 ms nsac 0
[56549.468525] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.468855] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00408002
[56549.468881] mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
[56549.468887] mmc0:     0 bytes transferred: -84
[56549.468902] mmcblk0: error -84 transferring data, sector 1, nr 7, cmd 
response 0x900, card status 0x0
[56549.468928] end_request: I/O error, dev mmcblk0, sector 1
[56549.468931] mmc0: starting CMD17 arg 00000002 flags 000000b5
[56549.468934] mmc0:     blksz 512 blocks 1 flags 00000200 tsac 100 ms nsac 0
[56549.468958] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.469295] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000002
[56549.469311] mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
[56549.469318] mmc0:     512 bytes transferred: 0
[56549.469340] mmc0: starting CMD17 arg 00000003 flags 000000b5
[56549.469347] mmc0:     blksz 512 blocks 1 flags 00000200 tsac 100 ms nsac 0
[56549.469382] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000001
[56549.469714] sdhci [sdhci_irq()]: *** mmc0 got interrupt: 0x00000002
[...]

Thanks,
        J


Revert patch:
index 0e02cc1..7d85245 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -42,6 +42,7 @@
 
 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 *);
@@ -606,10 +607,9 @@ 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_command *cmd)
+static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
 {
        u8 count;
-       struct mmc_data *data = cmd->data;
        unsigned target_timeout, current_timeout;
 
        /*
@@ -621,18 +621,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, 
struct mmc_command *cmd)
        if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
                return 0xE;
 
-       /* Unspecified timeout, assume max */
-       if (!data && !cmd->cmd_timeout_ms)
-               return 0xE;
-
        /* timeout in us */
-       if (!data)
-               target_timeout = cmd->cmd_timeout_ms * 1000;
-       else {
-               target_timeout = data->timeout_ns / 1000;
-               if (host->clock)
-                       target_timeout += data->timeout_clks / host->clock;
-       }
+       target_timeout = data->timeout_ns / 1000 +
+               data->timeout_clks / host->clock;
+
+       if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
+               host->timeout_clk = host->clock / 1000;
 
        /*
         * Figure out needed cycles.
@@ -654,8 +648,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, 
struct mmc_command *cmd)
        }
 
        if (count >= 0xF) {
-               printk(KERN_WARNING "%s: Too large timeout requested for 
CMD%d!\n",
-                      mmc_hostname(host->mmc), cmd->opcode);
+               printk(KERN_WARNING "%s: Too large timeout requested!\n",
+                       mmc_hostname(host->mmc));
                count = 0xE;
        }
 
@@ -673,21 +667,15 @@ 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_command 
*cmd)
+static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
 {
        u8 count;
        u8 ctrl;
-       struct mmc_data *data = cmd->data;
        int ret;
 
        WARN_ON(host->data);
 
-       if (data || (cmd->flags & MMC_RSP_BUSY)) {
-               count = sdhci_calc_timeout(host, cmd);
-               sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
-       }
-
-       if (!data)
+       if (data == NULL)
                return;
 
        /* Sanity checks */
@@ -699,6 +687,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
struct mmc_command *cmd)
        host->data_early = 0;
        host->data->bytes_xfered = 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;
 
@@ -964,7 +955,7 @@ static void sdhci_send_command(struct sdhci_host *host, 
struct mmc_command *cmd)
 
        host->cmd = cmd;
 
-       sdhci_prepare_data(host, cmd);
+       sdhci_prepare_data(host, cmd->data);
 
        sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
 
@@ -2504,12 +2495,9 @@ int sdhci_add_host(struct sdhci_host *host)
        if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
                host->timeout_clk *= 1000;
 
-       if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
-               host->timeout_clk = mmc->f_max / 1000;
-
        mmc->max_discard_to = (1 << 27) / host->timeout_clk;
 
-       mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
+       mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_CMD23;
 
        if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
                host->flags |= SDHCI_AUTO_CMD12;


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

Reply via email to