summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/sdio_io.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2007-08-08 14:23:48 +0100
committerPierre Ossman <drzeus@drzeus.cx>2007-09-23 21:19:26 +0200
commit9a08f82b3cc522f727ace580a2aaee5402435bc8 (patch)
tree81818bba503a469184883b0ea8c436b9ce97aa0f /drivers/mmc/core/sdio_io.c
parent7616ee95f27a04fd5a6434e9ef4a82cec4b2807c (diff)
sdio: set the functions' block size
Before a driver is probed, set the function's block size to the default so the driver is sure the block size is something sensible and it needn't explicitly set it. The default block size is the largest that's supported by both the card and the host, with a maximum of 512 to ensure aribitrarily sized transfer use the optimal (least) number of commands. See http://lkml.org/lkml/2007/8/7/150 for reasons for the block size choice. Signed-off-by: David Vrabel <david.vrabel@csr.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/sdio_io.c')
-rw-r--r--drivers/mmc/core/sdio_io.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index ecdb77242e98..c2bad1195e3b 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -141,6 +141,55 @@ err:
EXPORT_SYMBOL_GPL(sdio_disable_func);
/**
+ * sdio_set_block_size - set the block size of an SDIO function
+ * @func: SDIO function to change
+ * @blksz: new block size or 0 to use the default.
+ *
+ * The default block size is the largest supported by both the function
+ * and the host, with a maximum of 512 to ensure that arbitrarily sized
+ * data transfer use the optimal (least) number of commands.
+ *
+ * A driver may call this to override the default block size set by the
+ * core. This can be used to set a block size greater than the maximum
+ * that reported by the card; it is the driver's responsibility to ensure
+ * it uses a value that the card supports.
+ *
+ * Returns 0 on success, -EINVAL if the host does not support the
+ * requested block size, or -EIO (etc.) if one of the resultant FBR block
+ * size register writes failed.
+ *
+ */
+int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
+{
+ int ret;
+
+ if (blksz > func->card->host->max_blk_size)
+ return -EINVAL;
+
+ if (blksz == 0) {
+ blksz = min(min(
+ func->max_blksize,
+ func->card->host->max_blk_size),
+ 512u);
+ }
+
+ ret = mmc_io_rw_direct(func->card, 1, 0,
+ SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
+ blksz & 0xff, NULL);
+ if (ret)
+ return ret;
+ ret = mmc_io_rw_direct(func->card, 1, 0,
+ SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
+ (blksz >> 8) & 0xff, NULL);
+ if (ret)
+ return ret;
+ func->cur_blksize = blksz;
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(sdio_set_block_size);
+
+/**
* sdio_readb - read a single byte from a SDIO function
* @func: SDIO function to access
* @addr: address to read