diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2008-06-28 07:22:40 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-15 08:14:44 -0400 |
commit | eea0f581c4e596e02250df230f8d385827977964 (patch) | |
tree | 7c8c53b63c6cd5f6bcea49b53f3d436dccd6faa0 /drivers/mmc/core | |
parent | ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15 (diff) |
sdio: clean up handling of byte mode transfer size
Make sure that the maximum size for a byte mode transfer is identical
in all places. Also tweak the transfer helper so that a single byte
mode transfer is preferred over (possibly multiple) block mode
request(s).
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/sdio_io.c | 29 |
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 | |||
190 | EXPORT_SYMBOL_GPL(sdio_set_block_size); | 189 | EXPORT_SYMBOL_GPL(sdio_set_block_size); |
191 | 190 | ||
191 | /* | ||
192 | * Calculate the maximum byte mode transfer size | ||
193 | */ | ||
194 | static 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); |