* [PATCH][MMC] Bulk transfers (round 2)
@ 2005-03-16 14:25 Pierre Ossman
2005-03-16 14:35 ` Pierre Ossman
0 siblings, 1 reply; 2+ messages in thread
From: Pierre Ossman @ 2005-03-16 14:25 UTC (permalink / raw)
To: LKML, Russell King
I didn't get any response for this one either ;)
This is only a performance boost so it is less critical. It is very nice
to have though since the performance gain is substancial (>100%).
It should not pose any problems with data loss, which was your primary
concern. It backs down to single block transfers when an error is detected.
This patch has been downloaded almost 500 times and there have been no
errors reported that were related directly to the patch. The two errors
reported from using this was in the driver and with a buggy card (the
same one that needs the power cycle patch).
Kconfig default here is 'no' but 'yes' should be considered once it has
been tested on some more controllers.
Rgds
Pierre
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH][MMC] Bulk transfers (round 2)
2005-03-16 14:25 [PATCH][MMC] Bulk transfers (round 2) Pierre Ossman
@ 2005-03-16 14:35 ` Pierre Ossman
0 siblings, 0 replies; 2+ messages in thread
From: Pierre Ossman @ 2005-03-16 14:35 UTC (permalink / raw)
To: LKML, Russell King
[-- Attachment #1: Type: text/plain, Size: 47 bytes --]
it might help if I include the actual patch...
[-- Attachment #2: mmc-bulk.patch --]
[-- Type: text/x-patch, Size: 3619 bytes --]
Index: linux-wbsd/drivers/mmc/mmc_block.c
===================================================================
--- linux-wbsd/drivers/mmc/mmc_block.c (revision 77)
+++ linux-wbsd/drivers/mmc/mmc_block.c (working copy)
@@ -166,9 +166,25 @@
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
int ret;
+
+#ifdef CONFIG_MMC_BULKTRANSFER
+ int failsafe;
+#endif
if (mmc_card_claim_host(card))
goto cmd_err;
+
+#ifdef CONFIG_MMC_BULKTRANSFER
+ /*
+ * We first try transfering multiple blocks. If this fails
+ * we fall back to single block transfers.
+ *
+ * This gives us good performance when all is well and the
+ * possibility to determine which sector fails when all
+ * is not well.
+ */
+ failsafe = 0;
+#endif
do {
struct mmc_blk_request brq;
@@ -189,14 +205,32 @@
brq.stop.arg = 0;
brq.stop.flags = MMC_RSP_R1B;
+#ifdef CONFIG_MMC_BULKTRANSFER
+ /*
+ * A multi-block transfer failed. Falling back to single
+ * blocks.
+ */
+ if (failsafe)
+ brq.data.blocks = 1;
+
+#else
+ /*
+ * Writes are done one sector at a time.
+ */
+ if (rq_data_dir(req) != READ)
+ brq.data.blocks = 1;
+#endif
+
+ ret = 1;
+
if (rq_data_dir(req) == READ) {
brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
brq.data.flags |= MMC_DATA_READ;
} else {
- brq.cmd.opcode = MMC_WRITE_BLOCK;
+ brq.cmd.opcode = brq.data.blocks > 1 ? MMC_WRITE_MULTIPLE_BLOCK :
+ MMC_WRITE_BLOCK;
brq.cmd.flags = MMC_RSP_R1B;
brq.data.flags |= MMC_DATA_WRITE;
- brq.data.blocks = 1;
}
brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL;
@@ -204,19 +238,19 @@
if (brq.cmd.error) {
printk(KERN_ERR "%s: error %d sending read/write command\n",
req->rq_disk->disk_name, brq.cmd.error);
- goto cmd_err;
+ goto cmd_fail;
}
if (brq.data.error) {
printk(KERN_ERR "%s: error %d transferring data\n",
req->rq_disk->disk_name, brq.data.error);
- goto cmd_err;
+ goto cmd_fail;
}
if (brq.stop.error) {
printk(KERN_ERR "%s: error %d sending stop command\n",
req->rq_disk->disk_name, brq.stop.error);
- goto cmd_err;
+ goto cmd_fail;
}
do {
@@ -229,7 +263,7 @@
if (err) {
printk(KERN_ERR "%s: error %d requesting status\n",
req->rq_disk->disk_name, err);
- goto cmd_err;
+ goto cmd_fail;
}
} while (!(cmd.resp[0] & R1_READY_FOR_DATA));
@@ -255,6 +289,27 @@
end_that_request_last(req);
}
spin_unlock_irq(&md->lock);
+
+#ifdef CONFIG_MMC_BULKTRANSFER
+ /*
+ * Go back to bulk mode if in failsafe mode.
+ */
+ failsafe = 0;
+#endif
+
+ continue;
+
+ cmd_fail:
+
+#ifdef CONFIG_MMC_BULKTRANSFER
+ if (failsafe)
+ goto cmd_err;
+ else
+ failsafe = 1;
+#else
+ goto cmd_err;
+#endif
+
} while (ret);
mmc_card_release_host(card);
Index: linux-wbsd/drivers/mmc/Kconfig
===================================================================
--- linux-wbsd/drivers/mmc/Kconfig (revision 96)
+++ linux-wbsd/drivers/mmc/Kconfig (working copy)
@@ -41,6 +41,15 @@
mount the filesystem. Almost everyone wishing MMC support
should say Y or M here.
+config MMC_BULKTRANSFER
+ bool "Multi-block writes (EXPERIMENTAL)"
+ depends on MMC_BLOCK != n && EXPERIMENTAL
+ default n
+ help
+ By default all writes are done one sector at a time. Enable
+ this option to transfer as large blocks as the host supports.
+ The transfer speed is in most cases doubled.
+
config MMC_ARMMMCI
tristate "ARM AMBA Multimedia Card Interface support"
depends on ARM_AMBA && MMC
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2005-03-16 14:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-16 14:25 [PATCH][MMC] Bulk transfers (round 2) Pierre Ossman
2005-03-16 14:35 ` Pierre Ossman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox