[MMC] extend data timeout for writes
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Tue, 2 May 2006 16:24:59 +0000 (17:24 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 2 May 2006 16:24:59 +0000 (17:24 +0100)
The CSD contains a "read2write factor" which determines the multiplier to
be applied to the read timeout to obtain the write timeout.  We were
ignoring this parameter, resulting in the possibility for writes being
timed out too early.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/mmc.c
drivers/mmc/mmc_block.c
include/linux/mmc/card.h

index da6ddd910fc513d8ad8552fa575984485899a653..05aa4d6b4f24d1516e4b17031a76b5b91e81ea74 100644 (file)
@@ -549,6 +549,7 @@ static void mmc_decode_csd(struct mmc_card *card)
                csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
                csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
                csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+               csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
                csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
                csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
        } else {
@@ -583,6 +584,7 @@ static void mmc_decode_csd(struct mmc_card *card)
                csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
                csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
                csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+               csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
                csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
                csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
        }
index 8eb2a2ede64b5c1272515c7f2d37150a5eb792df..06bd1f4cb9b1e34c71255ef2c2f6711d0dbbbfc1 100644 (file)
@@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        brq.cmd.opcode = MMC_WRITE_BLOCK;
                        brq.data.flags |= MMC_DATA_WRITE;
                        brq.data.blocks = 1;
+
+                       /*
+                        * Scale up the timeout by the r2w factor
+                        */
+                       brq.data.timeout_ns <<= card->csd.r2w_factor;
+                       brq.data.timeout_clks <<= card->csd.r2w_factor;
                }
 
                if (brq.data.blocks > 1) {
index 30dd978c1ec88e43f66a7e2e08c61a064a6a963e..991a37382a22e84ec1e15894688046a9e77a077e 100644 (file)
@@ -28,6 +28,7 @@ struct mmc_csd {
        unsigned short          cmdclass;
        unsigned short          tacc_clks;
        unsigned int            tacc_ns;
+       unsigned int            r2w_factor;
        unsigned int            max_dtr;
        unsigned int            read_blkbits;
        unsigned int            write_blkbits;