From patchwork Wed Oct 26 08:52:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Nilsson XK X-Patchwork-Id: 4824 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id E6B4723E0C for ; Wed, 26 Oct 2011 08:58:46 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id CC652A18B8E for ; Wed, 26 Oct 2011 08:58:46 +0000 (UTC) Received: by faan26 with SMTP id n26so1881698faa.11 for ; Wed, 26 Oct 2011 01:58:46 -0700 (PDT) Received: by 10.223.91.143 with SMTP id n15mr52338117fam.23.1319619526601; Wed, 26 Oct 2011 01:58:46 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.1.71 with SMTP id 7cs5543lak; Wed, 26 Oct 2011 01:58:46 -0700 (PDT) Received: by 10.14.9.224 with SMTP id 72mr3873eet.152.1319619525371; Wed, 26 Oct 2011 01:58:45 -0700 (PDT) Received: from eu1sys200aog110.obsmtp.com (eu1sys200aog110.obsmtp.com. [207.126.144.129]) by mx.google.com with SMTP id e78si221084eee.145.2011.10.26.01.58.43 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 26 Oct 2011 01:58:45 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of stefan.xk.nilsson@stericsson.com) client-ip=207.126.144.129; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of stefan.xk.nilsson@stericsson.com) smtp.mail=stefan.xk.nilsson@stericsson.com Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP; Wed, 26 Oct 2011 08:58:45 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 85186190; Wed, 26 Oct 2011 08:58:29 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id ECA034D; Wed, 26 Oct 2011 08:52:27 +0000 (GMT) Received: from exdcvycastm004.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm004", Issuer "exdcvycastm004" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 8A9F424C080; Wed, 26 Oct 2011 10:52:22 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.2) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 26 Oct 2011 10:52:27 +0200 From: Stefan Nilsson XK To: , Chris Ball Cc: Per Forlin , Ulf Hansson , Stefan Nilsson XK Subject: [PATCH] mmc: sdio: Fix to support any block size optimally Date: Wed, 26 Oct 2011 10:52:17 +0200 Message-ID: <1319619137-17156-1-git-send-email-stefan.xk.nilsson@stericsson.com> X-Mailer: git-send-email 1.7.7 MIME-Version: 1.0 This patch allows any block size to be set on the SDIO link, and still have an arbitrary sized packet (adjusted in size by using sdio_align_size) transferred in an optimal way (preferably one transfer). Previously if the block size was larger than the default of 512 bytes and the transfer size was exactly one block size (possibly thanks to using sdio_align_size to get an optimal transfer size), it was sent as a number of byte transfers instead of one block transfer. Also if the number of blocks was (max_blocks * N) + 1, the tranfer would be conducted with a number of blocks and finished off with a number of byte transfers. When doing this change it was also possible to break out the quirk for broken byte mode in a much cleaner way, and collect the logic of when to do byte or block transfer in one function instead of two. Signed-off-by: Stefan Nilsson XK Signed-off-by: Ulf Hansson Acked-by: Linus Walleij --- drivers/mmc/core/sdio_io.c | 8 ++++++-- drivers/mmc/core/sdio_ops.c | 14 +++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 0f687cd..b20fbb4 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -195,6 +195,9 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) else mval = min(mval, func->max_blksize); + if (mmc_card_broken_byte_mode_512(func->card)) + return min(mval, 511u); + return min(mval, 512u); /* maximum size for byte mode */ } @@ -313,7 +316,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, func->card->host->max_seg_size / func->cur_blksize); max_blocks = min(max_blocks, 511u); - while (remainder > func->cur_blksize) { + while (remainder >= func->cur_blksize) { unsigned blocks; blocks = remainder / func->cur_blksize; @@ -338,8 +341,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, while (remainder > 0) { size = min(remainder, sdio_max_byte_size(func)); + /* Indicate byte mode by setting "blocks" = 0 */ ret = mmc_io_rw_extended(func->card, write, func->num, addr, - incr_addr, buf, 1, size); + incr_addr, buf, 0, size); if (ret) return ret; diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index b0517cc..d29e206 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c @@ -128,8 +128,6 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, BUG_ON(!card); BUG_ON(fn > 7); - BUG_ON(blocks == 1 && blksz > 512); - WARN_ON(blocks == 0); WARN_ON(blksz == 0); /* sanity check */ @@ -144,22 +142,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, cmd.arg |= fn << 28; cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; cmd.arg |= addr << 9; - if (blocks == 1 && blksz < 512) - cmd.arg |= blksz; /* byte mode */ - else if (blocks == 1 && blksz == 512 && - !(mmc_card_broken_byte_mode_512(card))) - cmd.arg |= 0; /* byte mode, 0==512 */ + if (blocks == 0) + cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ else cmd.arg |= 0x08000000 | blocks; /* block mode */ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; data.blksz = blksz; - data.blocks = blocks; + /* 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, blksz * blocks); + sg_init_one(&sg, buf, data.blksz * data.blocks); mmc_set_data_timeout(&data, card);