--- drivers/mmc/core/sdio_io.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) Index: linux-2.6.22-atheros-ng/drivers/mmc/core/sdio_io.c =================================================================== --- linux-2.6.22-atheros-ng.orig/drivers/mmc/core/sdio_io.c 2007-12-11 22:00:41.000000000 +0100 +++ linux-2.6.22-atheros-ng/drivers/mmc/core/sdio_io.c 2007-12-18 13:59:16.000000000 +0100 @@ -177,6 +177,11 @@ 512u); } + + blksz = 0x80; + + printk("######## BLOCK size: 0x%x ############## \n", blksz); + ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE, blksz & 0xff, NULL); @@ -254,6 +259,65 @@ return 0; } +int sdio_io_rw(struct sdio_func *func, int write, int block, int block_size, int block_count, + unsigned addr, int incr_addr, u8 *buf, unsigned size) +{ + unsigned remainder = size; + unsigned max_blocks; + int ret; + + /* Do the bulk of the transfer using block mode (if supported). */ + if (func->card->cccr.multi_block && block) { + /* 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(min( + func->card->host->max_blk_count, + func->card->host->max_seg_size / block_size), + 511u); + + while (remainder > block_size) { + if (block_count > max_blocks) { + printk("Request block count %d > max %d\n", block_count, max_blocks); + block_count = max_blocks; + } + size = block_count * block_size; + + ret = mmc_io_rw_extended(func->card, write, func->num, addr, + incr_addr, buf, block_count, block_size); + if (ret) + return ret; + + remainder -= size; + buf += size; + if (incr_addr) + addr += size; + } + } + + /* Write the remainder using byte mode. */ + while (remainder > 0) { + size = remainder; + if (size > block_size) + size = block_size; + if (size > 512) + size = 512; /* maximum size for byte mode */ + + ret = mmc_io_rw_extended(func->card, write, func->num, addr, + incr_addr, buf, 1, size); + if (ret) + return ret; + + remainder -= size; + buf += size; + if (incr_addr) + addr += size; + } + return 0; +} + +EXPORT_SYMBOL_GPL(sdio_io_rw); + /** * sdio_readb - read a single byte from a SDIO function * @func: SDIO function to access