All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mmc: sdio: To use multiple scatter gather list
@ 2012-10-22 11:01 Kyoungil Kim
  2012-10-29 21:20 ` Chris Ball
  0 siblings, 1 reply; 4+ messages in thread
From: Kyoungil Kim @ 2012-10-22 11:01 UTC (permalink / raw)
  To: linux-mmc; +Cc: 'Chris Ball', 'Kyoungil Kim'

We used only single sg entry for SDIO transfer.
This chagne is to use multiple sg entry.
In case of dwmci, it support only up to 4KB size per single sg entry.
So if we want to transfer more than 4KB, we should send more than 1 command.
This makes performance degradation for large data transfer.

Signed-off-by: Kyoungil Kim <ki0351.kim@samsung.com>
---
 drivers/mmc/core/sdio_io.c  |   10 +++-------
 drivers/mmc/core/sdio_ops.c |   33 +++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 8f6f5ac..78cb4d5 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -188,8 +188,7 @@ EXPORT_SYMBOL_GPL(sdio_set_block_size);
  */
 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
 {
-	unsigned mval =	min(func->card->host->max_seg_size,
-			    func->card->host->max_blk_size);
+	unsigned mval =	func->card->host->max_blk_size;
 
 	if (mmc_blksz_for_byte_mode(func->card))
 		mval = min(mval, func->cur_blksize);
@@ -311,11 +310,8 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
 	/* Do the bulk of the transfer using block mode (if supported). */
 	if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
 		/* Blocks per command is limited by host count, host transfer
-		 * size (we only use a single sg entry) and the maximum for
-		 * IO_RW_EXTENDED of 511 blocks. */
-		max_blocks = min(func->card->host->max_blk_count,
-			func->card->host->max_seg_size / func->cur_blksize);
-		max_blocks = min(max_blocks, 511u);
+		 * size and the maximum for IO_RW_EXTENDED of 511 blocks. */
+		max_blocks = min(func->card->host->max_blk_count, 511u);
 
 		while (remainder >= func->cur_blksize) {
 			unsigned blocks;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index d29e206..ac01352 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -124,7 +124,10 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
 	struct mmc_data data = {0};
-	struct scatterlist sg;
+	struct scatterlist sg, *sg_ptr;
+	struct sg_table sgtable;
+	unsigned int nents, left_size, i;
+	unsigned int seg_size = card->host->max_seg_size;
 
 	BUG_ON(!card);
 	BUG_ON(fn > 7);
@@ -152,15 +155,37 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	/* Code in host drivers/fwk assumes that "blocks" always is >=1 */
 	data.blocks = blocks ? blocks : 1;
 	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
-	data.sg = &sg;
-	data.sg_len = 1;
 
-	sg_init_one(&sg, buf, data.blksz * data.blocks);
+	left_size = data.blksz * data.blocks;
+	nents = (left_size - 1) / seg_size + 1;
+	if (nents > 1) {
+		if (sg_alloc_table(&sgtable, nents, GFP_KERNEL))
+			return -ENOMEM;
+
+		data.sg = sgtable.sgl;
+		data.sg_len = nents;
+
+		for_each_sg(data.sg, sg_ptr, data.sg_len, i) {
+			sg_set_page(sg_ptr, virt_to_page(buf + (i * seg_size)),
+					min(seg_size, left_size),
+					offset_in_page(buf + (i * seg_size)));
+			left_size = left_size - seg_size;
+		}
+	} else {
+		data.sg = &sg;
+		data.sg_len = 1;
+
+		sg_init_one(&sg, buf, left_size);
+	}
 
 	mmc_set_data_timeout(&data, card);
 
 	mmc_wait_for_req(card->host, &mrq);
 
+	if (nents > 1)
+		sg_free_table(&sgtable);
+
+
 	if (cmd.error)
 		return cmd.error;
 	if (data.error)
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-11-17 20:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-22 11:01 [PATCH] mmc: sdio: To use multiple scatter gather list Kyoungil Kim
2012-10-29 21:20 ` Chris Ball
2012-11-07  5:16   ` Kyoungil Kim
2012-11-17 20:26     ` Chris Ball

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.