aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sdio_io.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 6ee7861fceae..cc42a41ff6ab 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -186,9 +186,20 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
186 func->cur_blksize = blksz; 186 func->cur_blksize = blksz;
187 return 0; 187 return 0;
188} 188}
189
190EXPORT_SYMBOL_GPL(sdio_set_block_size); 189EXPORT_SYMBOL_GPL(sdio_set_block_size);
191 190
191/*
192 * Calculate the maximum byte mode transfer size
193 */
194static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
195{
196 return min(min(min(
197 func->card->host->max_seg_size,
198 func->card->host->max_blk_size),
199 func->max_blksize),
200 512u); /* maximum size for byte mode */
201}
202
192/** 203/**
193 * sdio_align_size - pads a transfer size to a more optimal value 204 * sdio_align_size - pads a transfer size to a more optimal value
194 * @func: SDIO function 205 * @func: SDIO function
@@ -222,7 +233,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
222 * If we can still do this with just a byte transfer, then 233 * If we can still do this with just a byte transfer, then
223 * we're done. 234 * we're done.
224 */ 235 */
225 if ((sz <= func->cur_blksize) && (sz <= 512)) 236 if (sz <= sdio_max_byte_size(func))
226 return sz; 237 return sz;
227 238
228 if (func->card->cccr.multi_block) { 239 if (func->card->cccr.multi_block) {
@@ -253,7 +264,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
253 */ 264 */
254 byte_sz = mmc_align_data_size(func->card, 265 byte_sz = mmc_align_data_size(func->card,
255 sz % func->cur_blksize); 266 sz % func->cur_blksize);
256 if ((byte_sz <= func->cur_blksize) && (byte_sz <= 512)) { 267 if (byte_sz <= sdio_max_byte_size(func)) {
257 blk_sz = sz / func->cur_blksize; 268 blk_sz = sz / func->cur_blksize;
258 return blk_sz * func->cur_blksize + byte_sz; 269 return blk_sz * func->cur_blksize + byte_sz;
259 } 270 }
@@ -263,8 +274,8 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
263 * controller can handle the chunk size; 274 * controller can handle the chunk size;
264 */ 275 */
265 chunk_sz = mmc_align_data_size(func->card, 276 chunk_sz = mmc_align_data_size(func->card,
266 min(func->cur_blksize, 512u)); 277 sdio_max_byte_size(func));
267 if (chunk_sz == min(func->cur_blksize, 512u)) { 278 if (chunk_sz == sdio_max_byte_size(func)) {
268 /* 279 /*
269 * Fix up the size of the remainder (if any) 280 * Fix up the size of the remainder (if any)
270 */ 281 */
@@ -296,7 +307,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
296 int ret; 307 int ret;
297 308
298 /* Do the bulk of the transfer using block mode (if supported). */ 309 /* Do the bulk of the transfer using block mode (if supported). */
299 if (func->card->cccr.multi_block) { 310 if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
300 /* Blocks per command is limited by host count, host transfer 311 /* Blocks per command is limited by host count, host transfer
301 * size (we only use a single sg entry) and the maximum for 312 * size (we only use a single sg entry) and the maximum for
302 * IO_RW_EXTENDED of 511 blocks. */ 313 * IO_RW_EXTENDED of 511 blocks. */
@@ -328,11 +339,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
328 339
329 /* Write the remainder using byte mode. */ 340 /* Write the remainder using byte mode. */
330 while (remainder > 0) { 341 while (remainder > 0) {
331 size = remainder; 342 size = min(remainder, sdio_max_byte_size(func));
332 if (size > func->cur_blksize)
333 size = func->cur_blksize;
334 if (size > 512)
335 size = 512; /* maximum size for byte mode */
336 343
337 ret = mmc_io_rw_extended(func->card, write, func->num, addr, 344 ret = mmc_io_rw_extended(func->card, write, func->num, addr,
338 incr_addr, buf, 1, size); 345 incr_addr, buf, 1, size);