summary refs log tree commit diff
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.gz
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);