The patch titled

     mmc: Multi-sector writes

has been added to the -mm tree.  Its filename is

     mmc-multi-sector-writes.patch

Patches currently in -mm which might be from [EMAIL PROTECTED] are

sd-initialize-sd-cards.patch
sd-read-only-switch.patch
sd-read-only-switch-coding-style-fix.patch
sd-read-only-switch-mmc-sd-init-order-fix.patch
sd-read-only-switch-mmc-sd-ro-style-fix.patch
sd-scr-register.patch
sd-scr-register-mmc-sd-scr-style-fixpatch.patch
sd-scr-in-sysfs.patch
sd-4-bit-bus.patch
sd-copyright-notice.patch
mmc-multi-sector-writes.patch



From: Pierre Ossman <[EMAIL PROTECTED]>

Adds support for writing multiple sectors at once.  This allows
back-to-back transfers of sectors giving roughly double write throughput.

To be able to detect which sector is causing problems the system falls back
to single sector writes if a failure is detected.

Signed-off-by: Pierre Ossman <[EMAIL PROTECTED]>
Cc: Russell King <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/mmc/Kconfig     |    9 ++++++
 drivers/mmc/mmc_block.c |   67 +++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 70 insertions(+), 6 deletions(-)

diff -puN drivers/mmc/Kconfig~mmc-multi-sector-writes drivers/mmc/Kconfig
--- 25/drivers/mmc/Kconfig~mmc-multi-sector-writes      Wed Aug 17 15:52:31 2005
+++ 25-akpm/drivers/mmc/Kconfig Wed Aug 17 15:52:31 2005
@@ -29,6 +29,15 @@ config MMC_BLOCK
          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
diff -puN drivers/mmc/mmc_block.c~mmc-multi-sector-writes 
drivers/mmc/mmc_block.c
--- 25/drivers/mmc/mmc_block.c~mmc-multi-sector-writes  Wed Aug 17 15:52:31 2005
+++ 25-akpm/drivers/mmc/mmc_block.c     Wed Aug 17 15:52:31 2005
@@ -171,9 +171,25 @@ static int mmc_blk_issue_rq(struct mmc_q
        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;
                struct mmc_command cmd;
@@ -192,14 +208,32 @@ static int mmc_blk_issue_rq(struct mmc_q
                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;
 
@@ -210,19 +244,19 @@ static int mmc_blk_issue_rq(struct mmc_q
                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 {
@@ -235,7 +269,7 @@ static int mmc_blk_issue_rq(struct mmc_q
                        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));
 
@@ -261,6 +295,27 @@ static int mmc_blk_issue_rq(struct mmc_q
                        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);
_
-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to