summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-07-06 01:10:27 +0200
committerPierre Ossman <drzeus@drzeus.cx>2008-07-15 14:14:49 +0200
commit23af60398af2f5033e2f53665538a09f498dbc03 (patch)
treefc244139d7d6bb1a82b80cc60fae86970e60c8c5 /drivers/mmc/card
parent97067d5581ec831a75a45a52e417bee0f7943dbf (diff)
downloadlinux-23af60398af2f5033e2f53665538a09f498dbc03.tar.bz2
mmc: remove multiwrite capability
Relax requirements on host controllers and only require that they do not report a transfer count than is larger than the actual one (i.e. a lower value is okay). This is how many other parts of the kernel behaves so upper layers should already be prepared to handle that scenario. This gives us a performance boost on MMC cards. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/block.c47
1 files changed, 19 insertions, 28 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 4b0f8220f153..66e5a5487c20 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -237,17 +237,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
if (brq.data.blocks > card->host->max_blk_count)
brq.data.blocks = card->host->max_blk_count;
- /*
- * If the host doesn't support multiple block writes, force
- * block writes to single block. SD cards are excepted from
- * this rule as they support querying the number of
- * successfully written sectors.
- */
- if (rq_data_dir(req) != READ &&
- !(card->host->caps & MMC_CAP_MULTIWRITE) &&
- !mmc_card_sd(card))
- brq.data.blocks = 1;
-
if (brq.data.blocks > 1) {
/* SPI multiblock writes terminate using a special
* token, not a STOP_TRANSMISSION request.
@@ -367,30 +356,32 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
* mark the known good sectors as ok.
*
* If the card is not SD, we can still ok written sectors
- * if the controller can do proper error reporting.
+ * as reported by the controller (which might be less than
+ * the real number of written sectors, but never more).
*
* For reads we just fail the entire chunk as that should
* be safe in all cases.
*/
- if (rq_data_dir(req) != READ && mmc_card_sd(card)) {
- u32 blocks;
- unsigned int bytes;
-
- blocks = mmc_sd_num_wr_blocks(card);
- if (blocks != (u32)-1) {
- if (card->csd.write_partial)
- bytes = blocks << md->block_bits;
- else
- bytes = blocks << 9;
+ if (rq_data_dir(req) != READ) {
+ if (mmc_card_sd(card)) {
+ u32 blocks;
+ unsigned int bytes;
+
+ blocks = mmc_sd_num_wr_blocks(card);
+ if (blocks != (u32)-1) {
+ if (card->csd.write_partial)
+ bytes = blocks << md->block_bits;
+ else
+ bytes = blocks << 9;
+ spin_lock_irq(&md->lock);
+ ret = __blk_end_request(req, 0, bytes);
+ spin_unlock_irq(&md->lock);
+ }
+ } else {
spin_lock_irq(&md->lock);
- ret = __blk_end_request(req, 0, bytes);
+ ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
spin_unlock_irq(&md->lock);
}
- } else if (rq_data_dir(req) != READ &&
- (card->host->caps & MMC_CAP_MULTIWRITE)) {
- spin_lock_irq(&md->lock);
- ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
- spin_unlock_irq(&md->lock);
}
mmc_release_host(card->host);