int bcm_sdio_cmd53(struct sdio_func *func, int write, unsigned addr, int incr_addr, u8 *buf, unsigned size,int bcm_fn0_cur_blk_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) { /* 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 / bcm_fn0_cur_blk_size), 511u); while (remainder > bcm_fn0_cur_blk_size) { unsigned blocks; blocks = remainder / bcm_fn0_cur_blk_size; if (blocks > max_blocks) blocks = max_blocks; size = blocks * bcm_fn0_cur_blk_size; ret = mmc_io_rw_extended(func->card, write, 0, addr, incr_addr, buf, blocks, bcm_fn0_cur_blk_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 > bcm_fn0_cur_blk_size) size = bcm_fn0_cur_blk_size; if (size > 512) size = 512; /* maximum size for byte mode */ ret = mmc_io_rw_extended(func->card, write, 0, addr, incr_addr, buf, 1, size); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } return 0; }
/* Split an arbitrarily sized data transfer into several * IO_RW_EXTENDED commands. */ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, 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 && (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); while (remainder > func->cur_blksize) { unsigned blocks; blocks = remainder / func->cur_blksize; if (blocks > max_blocks) blocks = max_blocks; size = blocks * func->cur_blksize; ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, blocks, func->cur_blksize); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } } /* Write the remainder using byte mode. */ while (remainder > 0) { size = min(remainder, sdio_max_byte_size(func)); /* Some of host controllers does not support non-power-of-two block sizes */ if (func->card->host->caps & MMC_CAP_POWER_OF_TWO_BLKSIZE) size = 1 << (fls(size) - 1); 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; }
/* Split an arbitrarily sized data transfer into several * IO_RW_EXTENDED commands. */ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, unsigned addr, int incr_addr, u8 *buf, unsigned size) { unsigned remainder = size; unsigned max_blocks; int ret; if (!func || (func->num > 7)) return -EINVAL; /* 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 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; blocks = remainder / func->cur_blksize; if (blocks > max_blocks) blocks = max_blocks; size = blocks * func->cur_blksize; ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, blocks, func->cur_blksize); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } } /* Write the remainder using byte mode. */ 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, 0, size); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } return 0; }
static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, unsigned addr, int incr_addr, u8 *buf, unsigned size) { unsigned remainder = size; unsigned max_blocks; int ret; if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) { max_blocks = min(func->card->host->max_blk_count, func->card->host->max_seg_size / func->cur_blksize); max_blocks = min(max_blocks, 511u); while (remainder >= func->cur_blksize) { unsigned blocks; blocks = remainder / func->cur_blksize; if (blocks > max_blocks) blocks = max_blocks; size = blocks * func->cur_blksize; ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, blocks, func->cur_blksize); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } } while (remainder > 0) { size = min(remainder, sdio_max_byte_size(func)); ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, 0, size); if (ret) return ret; remainder -= size; buf += size; if (incr_addr) addr += size; } return 0; }
/* * Split an arbitrarily sized data transfer into several * IO_RW_EXTENDED commands. */ int sdio_io_rw_ext_helper(struct sdio_func *func, int write, unsigned addr, int incr_addr, u8 *buf, unsigned size) { unsigned remainder = size; int ret; /* Do the bulk of the transfer using block mode (if supported). */ if (func->card->cccr.multi_block) { while (remainder > func->cur_blksize) { unsigned blocks; blocks = remainder / func->cur_blksize; if (blocks > max_blocks) blocks = max_blocks; size = blocks * func->cur_blksize; ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, blocks, func->cur_blksize); 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 > func->cur_blksize) size = func->cur_blksize; 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; }